如何使用 Azure Ad client_credentials 对服务器到服务器通信的后端 Web api 进行身份验证

DaI*_*mTo 3 curl oauth azure asp.net-web-api azure-active-directory

我有一个curl 脚本,它从Azure AD 请求新的访问令牌。我需要它为我的 API 返回某种类型的声明,角色或范围都可以。

我可以获得访问令牌,但它不会返回角色声明或范围或任何此类性质的内容。

在 Web API 中使用时

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)                 
   .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));
Run Code Online (Sandbox Code Playgroud)

我得到:

在不记名令牌中找不到范围或角色声明。

我确实尝试过设置

"AllowWebApiToBeAuthorizedByACL" : true,
Run Code Online (Sandbox Code Playgroud)

appsettings.json中,但它并没有像预期那样阻止错误的发生。

这用于在curl脚本和微服务之间进行授权。由于它是后台服务,因此没有用户交互,它只是服务器到服务器的授权。我只是想保护 Web api。因此,出于安全原因,我想确保创建的访问令牌实际上是该系统的访问令牌,这就是为什么我在我的应用程序上寻找某种声明或角色,以确保它不仅仅是来自另一部分的随机访问令牌系统的。

如果没有角色或范围,我的应用程序将引发以下错误

System.UnauthorizedAccessException:IDW10201:在不记名令牌中找不到范围或角色声明。

Oauth2 使用范围来使用户能够授予客户端对其数据的访问权限,因为这不需要我认为我正在寻找的不是范围。我认为我需要的是一种为应用程序本身定义角色的方法。我对蔚蓝的经验很少,所以如果我错了,请纠正我。

卷曲脚本

curl -X POST -d“grant_type=client_credentials&client_id=api://a4994a31-c494-4b73-9622-d3a7144abeee&client_secret=[secret]&resource=api://a4994a31-c494-4b73-9622-d3a7144abeee” https://login. microsoftonline.com/1e2ad6d6-274f-43e8-89ef-d36d65bb83b5/oauth2/token

回复

    {
      "aud": "api://a4994a31-c494-4b73-9622-d3a7144abee",
      "iss": "https://sts.windows.net/1e2ad6d6-274f-43e8-89ef-d36d6583b5/",
      "iat": 1628506854,
      "nbf": 1628506854,
      "exp": 1628510754,
      "aio": "E2ZgYChZ8/PRc/eJ5sYfulfVXWUrBQA=",
      "appid": "a4994a31-c494-4b73-9622-d3a7144abeee",
      "appidacr": "1",
      "idp": "https://sts.windows.net/1e2ad6d6-274f-43e8-89ef-d36d65bb835/",
      "oid": "81f74198-ab14-4b0b-bad6-62893e15f9c8",
      "rh": "0.AQsA1tYqHk8n6EOJ79NtZbuDtTFKmaSUxHNLliLTpxRKvu4AAA.",
      "sub": "81f74198-ab14-4b0b-bad6-62893e15f9c",
      "tid": "1e2ad6d6-274f-43e8-89ef-d36d65bb83b",
      "uti": "FaZGzuuRn0eEQYPRReoYAQ",
      "ver": "1.0"
    }
Run Code Online (Sandbox Code Playgroud)

我尝试设置范围

在此输入图像描述

然后将其添加到curl脚本中

卷曲-X POST -d“grant_type=client_credentials&client_id=api://a4994a31-c494-4b73-9622-d3a7144abeee&client_secret=[秘密]&resource=api://a4994a31-c494-4b73-9622-d3a7144abeee&scope=api://a4994a31- c494-4b73-9622-d3a7144abeee/load_scope“ https://login.microsoftonline.com/1e2ad6d6-274f-43e8-89ef-d36d65bb83b5/oauth2/token

完全没有效果,访问令牌仍然不包含任何范围。

然后我尝试添加一个角色

在此输入图像描述

添加将角色添加到资源

卷曲-X POST -d“grant_type=client_credentials&client_id=api://a4994a31-c494-4b73-9622-d3a7144abeee&client_secret=[秘密]&resource=api://a4994a31-c494-4b73-9622-d3a7144abeee/load”https: // login.microsoftonline.com/1e2ad6d6-274f-43e8-89ef-d36d65bb83b5/oauth2/token

但这只会返回一个错误

{“error”:“invalid_resource”,“error_description”:“AADSTS500011:在名为 1e2ad6d6-274f-43e8-89ef 的租户中找不到名为 api://a4994a31-c494-4b73-9622-d3a7144abeee/load 的资源主体- d36d65bb83b5。如果应用程序未经租户管理员安装或未经租户中的任何用户同意,则可能会发生这种情况。您可能已将身份验证请求发送给了错误的租户。

显现

我目前正在关注 将应用程序角色分配给应用程序这是清单。

"appId": "51bdea30-a886-47f7-a27f-994c8caca5c",
    "appRoles": [
        {
            "allowedMemberTypes": [
                "Application"
            ],
            "description": "myapprole",
            "displayName": "myapprole",
            "id": "bdaa8bc7-e0b3-47b1-b92-9011313e16ae",
            "isEnabled": true,
            "lang": null,
            "origin": "Application",
            "value": "myapprole"
        }
    ],
Run Code Online (Sandbox Code Playgroud)

DaI*_*mTo 8

解决方案是添加AllowWebApiToBeAuthorizedByACL此内容以删除错误消息,并允许后端服务无需角色或声明即可进行通信。

System.UnauthorizedAccessException:IDW10201:在不记名令牌中找不到范围或角色声明。

我已经添加了它,但在深入研究 Microsoft.Identity.Web 的源代码后它不起作用。我发现我使用的是旧版本的 Microsoft.Identity.Web,这显然是在添加检查之前AllowWebApiToBeAuthorizedByACL。我删除了 NuGet 包并在 1.15.2 中读取它并且它可以工作。

 "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "[Redacted]",
    "ClientId": "[Redacted]",
    "TenantId": "[Redacted]",
    "AllowWebApiToBeAuthorizedByACL" : true,
    "CallbackPath": "/signin-oidc"
  },
Run Code Online (Sandbox Code Playgroud)