Приложение-функция Azure с использованием CSOM и Azure AD для проверки подлинности

Я не уверен, возможно ли это, но моя цель - приложение-функция Azure, которое может использовать CSOM SharePoint. Я застрял в том, как выполнить авторизацию без учетных данных. Я собрал приведенный ниже код по кусочкам, но он выдает ошибку 401 unauthorized. Это может быть проблема конфигурации, с которой у меня были проблемы при создании приложения JavaScript и веб-API. Но мне также интересно, возможно ли это вообще или я иду неправильно. Некоторые ключевые моменты перед кодом:

  1. Мое демонстрационное приложение внешнего интерфейса было создано с секретом, который будет использоваться при аутентификации
  2. Демонстрационному приложению My Api были предоставлены разрешения API для Azure AD, Microsoft Graph и SharePoint.
  3. Демонстрационное приложение My Api предоставило API, а демонстрационное приложение внешнего интерфейса было добавлено как авторизованное клиентское приложение.
private static async Task ProcessMessageAsync(string myQueueItem, ILogger log)
{
    const string mName = "ProcessMessageAsync()";
    string resource = "https://my-Portal.onmicrosoft.com/demoapp-api"; //demoapp-api with permission to sharepoint
    string clientId = "guid-of-demoapp-frontend"; //demoapp-frontend
    string clientSecret = "secret-from-demoapp-frontend"; //demoapp-frontend secret
    string siteUrl = "https://my-portal.sharepoint.com/sites/my-site"; //sharepoint site
    string authorityUri = "https://login.microsoftonline.com/my-portal.onmicrosoft.com";
    try
    {
        using (ClientContext ctx = await GetClientContext(authorityUri, siteUrl, resource, clientId, clientSecret))
        {
            Web web = ctx.Web;
            ctx.Load(web);
            ctx.ExecuteQuery();
            log.LogInformation($"found site : {web.Title}");
        }
    }
    catch (Exception ex) {
        Console.WriteLine("***Unexpected Exception in {0} *** : {1}", mName, ex.Message);
        log.LogInformation("***Unexpected Exception in {0} *** : {1}", mName, ex.Message);
        while (ex.InnerException != null)
        {
            ex = ex.InnerException;
            Console.WriteLine(ex.Message);
        }
    }
}
public async static Task<ClientContext> GetClientContext(string authorityuri, string siteUrl, string resource, string clientId, string clientSecret)
{
    AuthenticationContext authContext = new AuthenticationContext(authorityuri);
    AuthenticationResult ar = await GetAccessToken(authorityuri, resource, clientId, clientSecret);
    string token = ar.AccessToken;
    var ctx = new ClientContext(siteUrl);
    ctx.ExecutingWebRequest += (s, e) =>
    {
        e.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + ar.AccessToken;
    };
    return ctx;
}
static async Task<AuthenticationResult> GetAccessToken(string authority, string resource, string clientId, string clientSecret)
{
    var clientCredential = new ClientCredential(clientId, clientSecret);
    AuthenticationContext context = new AuthenticationContext(authority, false);
    AuthenticationResult authenticationResult = await context.AcquireTokenAsync(
        resource,  // the resource (app) we are going to access with the token
        clientCredential);  // the client credentials
    return authenticationResult;
}

Обновление. После дальнейшего исследования я думаю, что проблема может заключаться в том, что я использовал полномочия делегата, а вместо этого мне нужны разрешения приложения (которые требуют, чтобы у меня был доступ администратора в каталоге).


person pretzelb    schedule 20.11.2019    source источник


Ответы (1)


Вы получаете токен со следующим кодом:

    AuthenticationResult ar = await GetAccessToken(authorityuri, resource, clientId, clientSecret);
    string token = ar.AccessToken;

Однако полученный токен можно использовать только для доступа к ресурсу, указанному в качестве параметра. В вашем случае это "https://my-Portal.onmicrosoft.com/demoapp-api".

Таким образом, вы можете использовать этот токен только для доступа к веб-API конечной точки, а не напрямую к sharepoint.

person Jack Jia    schedule 21.11.2019
comment
У меня есть несколько статей, в которых утверждается, что это возможно. Например [ссылка] bob1german.com/2017/06/24/az- func-csom и [ссылка] mmsharepoint.wordpress.com/tag/csom - person pretzelb; 22.11.2019
comment
Проверил две статьи. Дело в том, что у них есть только одно приложение-функция Azure, другой конечной точки нет. И их ресурсы указаны как их сайт sharepoint. Итак, угрюмо, они получат правильные токены для доступа к своим сайтам sharepoint. Но ваш случай отличается от них. - person Jack Jia; 22.11.2019
comment
Я экспериментировал с кодом, чтобы более точно сопоставить эти ссылки, и я думаю, что проблема в том, что вам нужно предоставить приложению-функции не делегированные разрешения, и для этого требуется, чтобы вы были администратором каталога (а я не администратор) . - person pretzelb; 22.11.2019