如何解决代表api不是用户从另一个WebAp获取401 Unauthorized调用WebApi
我们在 Azure 中有许多代表用户调用的 ASPNET Core Web API。该用户通常已登录 ASPNET 网站,也在 Azure 中。
我们正在推出审计服务。感觉应该代表调用服务而不是经过身份验证的用户调用它。
- 审计服务在 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);
更新
我已通过应用清单将调用应用程序的 Azure 广告应用程序 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)
有什么想法吗?
解决方法
您当前应该执行服务器到服务器的交互,即没有用户参与。因此,您的服务器应用需要创建一个 appRole
,然后将应用角色作为应用权限授予客户端应用。
首先需要暴露Azure保护的服务器应用的api,可以按照如下流程进行配置:
Azure 门户>应用注册>公开 API>添加范围>添加客户端应用
然后您需要创建服务器应用程序的 appRole
,然后将该角色作为应用程序权限授予客户端应用程序。
接下来,转到客户端应用程序>API 权限>添加权限>我的 API>您的 API 应用程序。
最后,您需要在没有用户登录的情况下使用 client credential flow 获取访问令牌:
解析token:
,虽然我已将 Carl Zhao 的贡献标记为答案,但我发现屏幕截图有点难以理解,所以这是我试图使之更清晰一些的尝试。
在这种情况下,我们希望在 Azure Ad 注册应用程序(客户端)和另一个 Azure Ad 注册应用程序(审计服务)范围之间进行身份验证,这不是解决方案。我们需要公开 appRole,而不是公开范围。
公开然后请求访问应用角色所需的步骤是
- 应用注册 -> 审核服务 -> 管理 -> 应用角色 -> 创建应用角色
- 创建应用程序角色时,确保允许的成员类型为“应用程序”
- 现在转到应用注册 -> YourClientApplication -> Api 权限 -> 添加权限
- 我希望审计服务出现在“请求 API 权限面板”中的“我的 API”下。我没有,我可以请求对先前创建的 AppRole 进行许可的唯一方法是在“我的组织使用的 API”下的搜索框中输入审核服务的 AppId
- 选择审核服务后,我选择了“应用程序权限”而不是“委派权限”,然后选择了特定角色
一旦客户端应用程序被授予访问权限,我们就需要编写代码来获取访问令牌。使用 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"));
注意调用 GetAccessTokenForAppAsync 而不是 GetAccessTokenForUserAsync。 GetAccessTokenForAppAsync
仍然需要一个范围,但是如前所述,不需要自定义范围。范围是“.default”,所以在我们的例子中传递给该调用的字符串是 https://ourdomain/audit-service/.default”,它是我们的 App ID URI 加上“.default”
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。