首页 > 解决方案 > 使用 CSOM 和 Azure AD 进行身份验证的 Azure 函数应用

问题描述

我不确定这是否可行,但我的目标是一个可以使用 SharePoint CSOM 的 Azure 函数应用。我被困在如何在没有用户凭据的情况下进行授权。我拼凑了下面的代码,但它引发了未经授权的 401。这可能是我在执行 JavaScript 应用程序和 Web Api 时遇到的配置问题。但我也想知道这是否可行,或者我是否走错了路。代码前的一些关键点:

  1. 我的前端演示应用程序是使用用于身份验证的秘密创建的
  2. 我的 Api 演示应用被授予对 Azure AD、Microsoft Graph 和 SharePoint 的 API 权限
  3. 我的 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;
}

更新 经过进一步研究,我认为问题可能是我使用的是委托权限,而我需要应用程序权限(这要求我在目录中具有管理员访问权限)。

标签: authenticationazure-active-directoryazure-functionscsom

解决方案


您使用以下代码获得令牌:

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

但是,您获得的令牌只能用于访问您指定为参数的资源。在你的情况下,它是"https://my-Portal.onmicrosoft.com/demoapp-api".

因此,您只能使用该令牌来访问您的端点 Web API,而不是直接使用共享点。


推荐阅读