您如何从 Azure Active Directory 中获取搭建的 Weather Forecast Api 将接受的访问令牌?
Posted
技术标签:
【中文标题】您如何从 Azure Active Directory 中获取搭建的 Weather Forecast Api 将接受的访问令牌?【英文标题】:How do you get an Access Token from Azure Active Directory that the scaffolded Weather Forecast Api will accept? 【发布时间】:2021-02-12 10:31:37 【问题描述】:我正在尝试使用 azure 活动目录中的访问令牌构建一个新的 WebApi。
我正在使用 .net core v3.1 和 Visual Studio 2019。
我使用“Asp.net core web application”模板创建了一个新项目并选择了一个“API”项目并将身份验证类型更改为“Work or School Accounts”并将 App ID Url 设置为 Api://Automation /TestApi
Visual Studio 然后为我搭建了一个带有模拟天气预报服务的 Web API,如果我注释掉 [Authorize] 属性,它会在浏览器中按预期很好地启动。它还在 AzureActive Directory 中为我创建了一个应用程序注册。
重新设置 [Authorize] 属性后,我无法从客户端应用程序调用 API,因此我决定使用邮递员调用 API 以查看发生了什么。
我在创建的应用注册 Visual Studio 中添加了一个客户端密码,并使用应用程序(客户端)ID 和 api://Automation/TestApi/.default 作为范围将邮递员请求放在一起,如下所示。
这工作正常并返回访问令牌,但是当我尝试使用该访问令牌调用默认的天气预报端点时,我在 WWW-Authenticate 响应标头中收到 HTTP 401 未经授权的错误
"Bearer error="invalid_token", error_description="观众 'api://Automation/TestApi' 无效"
我有什么遗漏吗?我找不到任何关于观众应该是什么样的线索,也没有明显的控制方法。
这里请求的是公开 API 屏幕的内容
以及我正在使用的解码 jwt 令牌
更新
我在下面尝试了@CarlZhao 的答案,但并没有真正奏效。但是我记得a question I asked a while ago about the wrong issuer in the token 这样做的结果是手动编辑 API 注册中的清单 json 并设置“accessTokenAcceptedVersion”:2
现在我得到了一个以 clientId guid 作为受众的 v2 函数
但是,使用这个令牌还是不行!!我现在收到有关发行者的错误:
Bearer error="invalid_token", error_description="The issuer 'https://login.microsoftonline.com/guid/v2.0' is invalid
【问题讨论】:
我需要您提供两个屏幕截图: 1. 转到 AAD 门户>应用注册>您的应用>api 应用>公开一个 API。 2.使用jwt.ms解析你的访问令牌并提供截图。 附@CarlZhao 截图 【参考方案1】:您错过了一些重要步骤,您的访问令牌也错误,它缺少必要的权限。你可以试试我的方法:
你需要创建2个应用,一个代表客户端应用,一个代表api应用,然后使用客户端应用调用Web api应用。
首先需要暴露代表web api的应用的api,可以按照如下流程进行配置:
Azure 门户>应用注册>公开 API>添加范围>添加客户端应用程序
由于您使用的是客户端凭证流,接下来,您需要定义api应用程序的manifest,并将应用程序权限授予您的客户端应用程序(这是角色您自己定义的权限,您可以在添加权限时在My APIs中找到)。然后您需要单击管理员同意按钮授予管理员同意此权限。
This是定义清单的过程。
这是为客户端应用程序授予权限:
最后,您可以为您的 api 应用程序请求一个令牌:
解析令牌,你会看到:
【讨论】:
谢谢 Carl,我现在就试一试,我确实注意到您的访问令牌仍然具有与我相同的 aud 值,所以我希望它也会因同样的原因被拒绝。我还注意到,我们都从 V2 端点获取版本“1.0”令牌,这对我来说看起来很可疑。 我按照步骤进行了操作,包括我在之前的尝试中错过的清单步骤,但不幸的是,它不起作用 - 与以前相同的错误,您能否在答案中澄清 Test1 是客户端的应用注册和 Test2 是 API,当您请求令牌时,您是从客户端而不是 API 传递 clientId?【参考方案2】:我已经取得了一些进一步的进展,我将用它来提供我自己的答案。
生成的代码使用 Microsoft.AspNetCore.Authentication.AzureAD.UI 包 v 3.1.x 来验证令牌。
使用 Fiddler 我可以看到它使用的是较旧的端点,而不是当前的“V2.0”端点。
这样做的意义在于,令牌版本规定了令牌中返回的受众和发行者。
在 V1 令牌中,受众是来自应用注册的“Application Id Url”,发行者是“https://sts.windows.net/tennantId”
在 v2 令牌中,受众是应用程序注册的客户端 ID (GUID),发行者是 https://login.microsoftonline.com/tenantId/V2.0。
潜在的问题是这个库期望某种混合令牌,其受众价值为 v2.0 令牌(例如客户端 ID),但来自 v1 发行者https://sts.windows.net/。
我找不到让它查看 v2.0 端点进行配置的方法,但我在 git hub 上找到了一个 number of old issues,它有类似的问题,但没有解决就关闭了。
特别是
The issue with the incorrect audience Can not use v2.0 endpoints - causes the issuer problem我的解决方法是在应用注册上的应用注册“清单”json 中设置“accessTokenAcceptedVersion”:2。这可确保令牌中包含正确的受众。
第二步,在启动类的ConfigureServices方法中添加自定义颁发者验证。这是我的代码
AzureADOptions opt = new AzureADOptions();
Configuration.Bind("AzureAd", opt);
string expectedIssuer = $"opt.Instanceopt.TenantId/v2.0";
services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
options.TokenValidationParameters.IssuerValidator = (issuer, securityToken, validationParameters) =>
if (issuer == expectedIssuer) return issuer;
throw new SecurityTokenInvalidIssuerException("Invalid Issuer")
InvalidIssuer = issuer
;
;
);
这确实让我觉得我正在掩盖一个有缺陷和/或配置错误的中间件的根本问题,我不禁想到一定有更简单的东西 - 毕竟这是从 Visual Studio 2019 向导生成的入门代码。
【讨论】:
【参考方案3】:我找到了一种更好的方法,所以我想我会发布答案作为我第一个答案的替代方法。
我发现这很好 sample application and tutorial 并完成了第一部分“桌面应用程序调用 Web Api”,并生成了一个使用正确端点的 api,并以更可预测的方式处理验证令牌。如果您要说明一个新的 Web API,我建议使用它作为起点,而不是 Visual Studio 搭建的 api。
获取脚手架天气预报 api 以接受令牌和访问令牌
您需要为客户端和 api 以及 @Carl Zhao 建议的范围和上面链接的教程分别注册应用程序。 将 Microsoft.AspNetCore.Authentication.AzureAD.UI nuget 包替换为 Microsoft.Identity.Web 在配置服务的 startup.cs 中,将对 services.AddAuthentication(...).AddAzureAdBearer(....) 的调用替换为对 AddMicrosoftIdentityWebApiAuthentication 的调用 删除 Microsoft.AspNetCore.Authentication.* 的 using 指令并使用 Microsoft.Identity.Web 添加;这就是我的配置服务现在的样子
public void ConfigureServices(IServiceCollection services)
services.AddMicrosoftIdentityWebApiAuthentication(Configuration);
services.AddControllers();
我的其他答案中提供的自定义颁发者验证器不是必需的,可以删除。
【讨论】:
以上是关于您如何从 Azure Active Directory 中获取搭建的 Weather Forecast Api 将接受的访问令牌?的主要内容,如果未能解决你的问题,请参考以下文章
您如何从 Azure Active Directory 中获取搭建的 Weather Forecast Api 将接受的访问令牌?
从 Azure Active Directory 验证 JWT
Blazor 应用如何使用 Azure Active Directory 认证登录