1

我们代表用户调用 Azure 中的许多 ASPNET Core Web API。该用户通常已登录到同样在 Azure 中的 ASPNET 网站。

我们正在引入审计服务。感觉应该代表调用服务而不是经过身份验证的用户调用它。

  • 审计服务在 Azure AD 中有关联的应用注册
  • 审计服务有一个名为“access_as_application”的范围,虽然看过有关“.default”范围的文档,但我不确定我是否需要一个范围
  • 调用应用程序(ASPNET Core 网站)已添加到前面提到的范围的“授权客户端应用程序”部分

在调用应用程序中,我通过使用获取应用程序而不是用户的访问令牌 GetAccessTokenForAppAsync

var accessToken = await this.tokenAcquisition.GetAccessTokenForAppAsync(this.auditApiScope);
System.Diagnostics.Debug.WriteLine($"access token-{accessToken}");
this.httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
this.httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

目前我正在本地开发机器上运行调用应用程序和审计服务。

当我打电话给审计服务时,我收到了 401 Unauthorized

var response = await this.httpClient.PostAsync($"{this.auditApiBaseAddress}v1/entries", requestContent);

更新

我已通过 App Manifest 将调用应用程序的 Azure Ad App Id 添加为审计服务上的 knownClientApplication。这并没有阻止 401

"knownClientApplications": [
        "7ac7f49d-e9fa-4e1b-95b2-03e0e1981f58"
    ],

更新 2

我可以看到在 Visual Studio 中运行的服务实例正在报告堆栈跟踪。它指的是 IDW10201 问题。

System.UnauthorizedAccessException: IDW10201: Neither scope or roles claim was found in the bearer token. 
   at Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilderExtensions.<>c__DisplayClass3_1.<<AddMicrosoftIdentityWebApiImplementation>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilder.<>c__DisplayClass14_0.<<CallsWebApiImplementation>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

有什么想法为什么?

4

2 回答 2

0

您当前应该执行服务器到服务器的交互,即没有用户参与。所以你的服务器应用程序需要创建一个appRole,然后将app Role作为应用程序的权限授予客户端应用程序

首先需要暴露Azure保护的服务端应用的api ,可以按照如下流程进行配置:

Azure 门户>应用注册>公开 API>添加范围>添加客户端应用程序

在此处输入图像描述

然后您需要创建appRole服务器应用程序,然后将该角色作为应用程序权限授予客户端应用程序。

在此处输入图像描述

接下来,转到客户端应用程序>API 权限>添加权限>我的 APIs >您的 api 应用程序。

在此处输入图像描述

最后,您需要使用没有用户登录的客户端凭据流获取访问令牌:

在此处输入图像描述

解析token:</p>

在此处输入图像描述

于 2021-06-02T07:21:51.657 回答
0

虽然我已将 Carl Zhao 的贡献标记为答案,但我发现截图有点难以理解,所以这是我试图让它更清晰的尝试。

在这种情况下,我们希望 Azure Ad 注册应用程序(客户端)和另一个 Azure Ad 注册应用程序(审计服务)范围之间的身份验证不是解决方案。我们需要公开一个 appRole,而不是公开一个范围。

公开然后请求访问应用程序角色所需的步骤是

  1. 应用注册 -> 审核服务 -> 管理 -> 应用角色 -> 创建应用角色
  2. 创建应用角色时,确保允许的成员类型为“应用程序”
  3. 现在转到 App Registrations -> YourClientApplication -> Api 权限 -> 添加权限
  4. 我希望审计服务出现在“请求 API 权限面板”中的“我的 API”下。我没有,我可以请求对先前创建的 AppRole 的许可的唯一方法是在“我的组织使用的 API”下的搜索框中输入审计服务的 AppId
  5. 一旦我能够选择审计服务,我选择了“应用程序权限”而不是“委派权限”,然后我选择了特定角色

一旦客户端应用程序被授予访问权限,我们需要编写代码获取访问令牌。使用 Mictosoft.Identity.Web 库

var accessToken = await this.tokenAcquisition.GetAccessTokenForAppAsync(this.auditApiScope);
System.Diagnostics.Debug.WriteLine($"access token-{accessToken}");
this.httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
this.httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

请注意对 GetAccessTokenFor App Async 的调用,而不是 GetAccessTokenFor User Async。GetAccessTokenForAppAsync仍然需要一个范围,但如前所述,不需要自定义范围。范围是“.default”,因此在我们的案例中传递给该调用的字符串是 https://ourdomain/audit-service/.default”,这是我们的 App ID URI 加上“.default”

于 2021-06-03T10:52:20.187 回答