Невозможно проверить подлинность вызовов SharePoint REST или CSOM из.NET Core

У меня проблемы с доступом к SharePoint с использованием как CSOM, так и службы REST из консольного приложения.NET Core.

Сначала я создал консольное приложение, предназначенное для.NET Framework 4.6.1, установил пакет nuget Microsoft.SharePointOnline.CSOM и добавил два примера методов подключения к SharePoint с использованием жестко закодированных учетных данных пользователя. Это работает.

public static void CsomCall()
{
    var password = "password";
    var securePassword = new SecureString();
    foreach (var c in password.ToCharArray()) securePassword.AppendChar(c);

    using (ClientContext context = new ClientContext("https://siteurl"))
    {
        context.Credentials = new SharePointOnlineCredentials("user@domain", securePassword);
        Web web = context.Web;
        context.Load(web);
        context.ExecuteQuery();
        Console.WriteLine(web.Title);
    }
}
private static void RestCall()
{
    var password = "password";
    var securePassword = new SecureString();
    foreach (var c in password.ToCharArray()) securePassword.AppendChar(c);

    var credentials = new SharePointOnlineCredentials("user@domain", securePassword);

    using (WebClient client = new WebClient())
    {
        client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
        client.Credentials = credentials;
        client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
        client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");
        var content = client.DownloadString("https://siteurl/_api/web/lists");
        Console.WriteLine(content);
    }
}

Затем я создал консольное приложение.NET Core и скопировал методы, описанные выше. Я понимаю, что SharePoint CSOM еще не поддерживается в.NET Core, поэтому я использовал предложенный здесь обходной путь и вручную ссылался на Microsoft.SharePoint.Client.Portable.dll, Microsoft.SharePoint.Client.Runtime.Portable.dll и Microsoft.SharePoint.Client.Runtime.Windows.dll.

Мне пришлось внести пару изменений, чтобы скомпилировать код:

  • .ExecuteQueryAsync() вместо .ExecuteQuery()

  • var credentials = new SharePointOnlineCredentials("user@domain", password); Обратите внимание, что пароль - это простая строка в Microsoft.SharePoint.Client.Runtime.Portable.

При запуске CsomCall происходит сбой при доступе к web.Title:

Microsoft.SharePoint.Client.PropertyOrFieldNotInitializedException: свойство или поле "Заголовок" не было инициализировано. Он не был запрошен или запрос не был выполнен. Это может потребоваться в явном виде.

При запуске RestCall происходит сбой с ошибкой на client.DownloadString:

System.Net.WebException: "Удаленный сервер возвратил ошибку: (401) Несанкционированный."

Можно ли настроить SharePointOnlineCredentials для работы с.NET Core? Поиск переполнения стека показывает, что это возможно, но я просто не могу заставить его работать.

В конечном итоге мы хотели бы создать службу веб-API с использованием ASP.NET Core для создания документов для внутренних пользователей (чтение шаблонов документов из SharePoint, создание нового документа и сохранение обратно в SharePoint). Использование CSOM или REST и запуск на ОС Windows на данный момент.

1 ответ

Решение

REST-вызов неверен. Вы должны получить токен, используя учетные данные. Кроме того, WebClient в основном устарел, вместо этого используйте класс HttpClient.

Посмотрите на этот пример:

public const string BaseUri = "https://example.sharepoint.com";
private static HttpClient _client;

public static void Initialize()
{
    SharePointOnlineCredentials currentCredentials = GetCredentialsHere();

    var handler = new HttpClientHandler
    {
        Credentials = currentCredentials
    };

    _client = new HttpClient(handler);

    // you are missing this line
    handler.CookieContainer.SetCookies(BaseUri, currentCredentials.GetAuthenticationCookie(BaseUri));
    _client.BaseAddress = BaseUri;
    _client.DefaultRequestHeaders.Clear();
    _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    _client.MaxResponseContentBufferSize = 2147483647;
}
Другие вопросы по тегам