如何使用 Azure Functions 强制执行 AAD 应用程序角色授权?

How to enforce AAD Application Role authorization with Azure Functions?

This page 描述了如何使用清单将 Application 应用程序角色添加到 Azure Active Directory 中的应用程序。

页面中的代码示例:

"appId": "8763f1c4-f988-489c-a51e-158e9ef97d6a",
"appRoles": [
    {
      "allowedMemberTypes": [
        "Application"
      ],
      "displayName": "ConsumerApps",
      "id": "47fbb575-859a-4941-89c9-0f7a6c30beac",
      "isEnabled": true,
      "description": "Consumer apps have access to the consumer data.",
      "value": "Consumer"
    }
  ],
"availableToOtherTenants": false,

从使用 client_credentials 授权类型进行身份验证的应用程序调用 Azure 函数时,如何强制它属于应用程序角色?

我用 Google 搜索过,但未能找到解释如何为 Azure Functions 完成此授权的清晰文档。


我的测试功能应用程序

我从 Postman 调用的 Azure 门户中创建了一个简单的 "hello <name>" Azure 函数。

#r "Microsoft.Azure.WebJobs.Extensions.Http"
#r "Newtonsoft.Json"

using System.Net;
using System.Security.Claims;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;


public static IActionResult Run(HttpRequest req,  ILogger log, ClaimsPrincipal claimsPrincipal)
{
    var name = req.Query["name"];
    log.LogInformation($"C# HTTP trigger function processed a request: {name}");

    var cp = new {
        Identity = new {
            claimsPrincipal.Identity.AuthenticationType,
            claimsPrincipal.Identity.IsAuthenticated,
            claimsPrincipal.Identity.Name
        },
        Claims = claimsPrincipal.Claims.Select(claim => new
        {
            claim.Type,
            claim.Value
        })
    };
    log.LogInformation($"ClaimsPrincipal ({claimsPrincipal.GetType().FullName}): {JsonConvert.SerializeObject(cp, Formatting.Indented)}");

    return (IActionResult)new OkObjectResult($"Hello, {name}");
}

首先,我使用 https://login.microsoftonline.com/<Tenant ID>/oauth2/v2.0/token 进行身份验证并捕获 access_token

请求Body示例:

grant_type:client_credentials
client_id:<Application ID>
client_secret:<Client Secret>
scope:https://<Function-app-name>.azurewebsites.net/.default

示例结果:

{
    "token_type": "Bearer",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "access_token": "eyJ0eXAi......"
}

然后我使用 https://<function-app-name>.azurewebsites.net/api/hello?name=World 和包含 Authorization: Bearer eyJ0eXAi.......

的 header 调用我的 Azure 函数

身份验证工作正常,调用 Azure 函数也是如此。但是,我可以通过 Azure 门户中的 App registrations 添加一个新的应用程序,进行身份验证,然后自由调用 Azure 函数。我不知道如何将 Azure 函数的访问限制为仅具有特定应用程序角色的应用程序。

I don't know how to restrict access the Azure Function to only Applications that have a specific application role.

如果您只想让拥有ConsumerApps权限的App访问您的功能,请按照以下步骤操作。

1.Navigate 到您在门户中的 Azure Active Directory 中的 AD App -> 单击 Managed application in local directory -> Properties -> 设置 User assignment requiredYes.

2.Then你可以尝试用你的AD应用再次获取token,你会发现应用无法成功获取token,你会得到如下错误,因为你的客户端应用没有ConsumerApps 权限。

3.To功能接入成功,只需要为您使用的客户端AD App添加Application权限即可

在门户中导航到客户端 AD 应用 -> API permissions -> Add a permission -> 单击 APIs my organization uses -> 搜索您的功能 AD 应用名称 -> 单击该应用-> Application permissions -> 添加 Consumer 权限 -> 单击 Grant admin consent for xxx 按钮

稍等片刻,再次尝试获取token,正常。

使用令牌调用函数,也可以。