我创建了一个用azure活动目录保护的webapi。我现在需要测试它并尝试使用带有授权标头的fiddler。我正在尝试使用以下代码生成令牌。
Target obj = (Target)cmbTarget.SelectedItem;
AuthenticationResult authenticationResult;
string aadInstance = obj.AADInstance; // "https://login.windows.net/{0}";
string tenant = obj.Tenant; //"rudderless.onmicrosoft.com";
string apiResourceId = obj.ApiResourceId; //"15b4ac7f-23a8-4958-96a5-64159254690d";
string clientId = obj.ClientId; // "47cdc6c3-226a-4c38-b08e-055be8409056";
Uri redirectUri = new Uri(obj.RedirectUri); //new Uri("http://nativeclient");
string authority = string.Format(aadInstance, tenant);
authContext = new AuthenticationContext(authority);
authenticationResult = this.authContext.AcquireToken(apiResourceId,
clientId, redirectUri, PromptBehavior.Always);
txtToken.Text = authenticationResult.AccessToken;
Clipboard.SetText($"Bearer {txtToken.Text}");
我成功生成令牌,当我使用令牌调用webapi时,它会抛出401消息
WWW-Authenticate:Bearer error =" invalid_token",error_description =" The 观众无效"
答案 0 :(得分:9)
问题
实施了这篇Protected web API: Code configuration文章中的说明之后,我收到了一条类似于OP的错误消息:
WWW-Authenticate:承载错误=“ invalid_token”,error_description =“ The 观众无效”
问题出在我的appsettings.json
文件中是我的AzureAd> ClientId设置。
解决方案
我更新了ASP.NET Core Web API应用程序的appsettings.json
文件,以便ClientId设置使用在我的应用程序注册>“公开API”下在portal.Azure.com中找到的“应用程序ID URI”。部分。
appsettings.json中的部分与此类似:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "XXXXXXXX-XXXXX-XXXXX-XXXXX-XXXXXXXXXX",
// ClientId = Portal.Azure.com > App Registration > Expose an API > "Application ID URI"
"ClientId": "api://XXXXX-XXXXXX-XXXXX-XXXX-XXXXXXXXX"
}
答案 1 :(得分:4)
我认为重新审视身份验证的不同步骤非常重要,希望通过讨论,您将能够解决您遇到的问题。
当客户端尝试获取资源的访问令牌时,需要向AAD指定要为其获取令牌的资源。客户端可以配置为调用多个资源,所有资源都具有不同的配置,因此期望资源始终在访问令牌请求中指定。
资源可以是资源的App ID GUID,也可以是在Resource上注册的有效App ID URI。 AAD应该能够根据您提供的值唯一标识您尝试访问的资源。但请注意,如果您使用App ID GUID,您将从AAD获取一个令牌,其中Audience声明是App ID GUID。或者,如果您使用应用程序ID URI,您将在令牌中看到该URI作为受众声明。
在这两种情况下,您都会获得“相同”资源的令牌,但令牌中的声明将以不同方式显示。此外,单个应用程序资源可能在其应用程序上注册了多个App ID URI。根据您在身份验证请求中使用的身份,您将在令牌中获得与您传入的资源参数匹配的不同受众群体声明。
最后,一旦获得令牌,您就会将其发送给资源API,后者将验证令牌以获取许多内容,例如:客户端ID声明,范围/角色声明,身份验证方法('acr “声明”,并且绝对观众声称符合他们的期望!
这意味着资源API最终需要说“我接受< App ID GUID>作为有效的受众声明”...或“我接受< App ID URI>作为有效的受众声明”。这种逻辑可以内置到您正在使用的库中(如OWIN),但是您需要确保在API端,为正在期望的受众正确配置它。如果您愿意,您可以这样做,以便您的API根本不检查受众声明!令牌中的所有声明都是纯文本,因此你可以真正做任何你想做的事情,但在这种情况下你不会有一个非常安全的API:]
一天结束时,我的预感是这个错误来自您自己的API,并且它正在发生,因为您尚未将您的应用配置为接受与您的资源的应用ID ID GUID相匹配的Audience声明(它看起来像什么当你根据代码样本获得令牌时,你正在通过。)
我希望这能解决你的问题!
答案 2 :(得分:1)
也可能是您的 app/lib 使用了较新版本的 api。 如果您的应用程序清单中的 accessTokenAcceptedVersion 为 null,则 ms 默认为 v1。 在 http://jwt.io 中检查您的 jwt 令牌 如果你得到这个 - 检查你的 JWT 令牌。如果ISS不是这样
"iss": "https://login.microsoftonline.com/[yadyada]/v2.0",
那么很可能您正在使用另一个版本(例如默认版本 1)。检查您的 azure 广告应用的清单: 下面的值可能是 null 或 1,应该是 2:
"accessTokenAcceptedVersion": 2,
答案 3 :(得分:0)
我有同样的问题。当我应该使用服务器的资源ID时,我使用客户端的资源ID作为AcquireToken的参数。
当我使用正确的资源ID时,它可以工作。
答案 4 :(得分:0)
在活动目录中调用api以通过App注册实现服务原理时。 我在使用承载键调用api-GET {vaultBaseUrl} / secrets / {secret-name} / {secret-version}?api-version = 7.0时遇到此错误,以获取密钥库机密值。 作为修复的一部分,为了获取承载值,除了传递clientid,客户端机密,grant_type外,我还添加了值为https://vault.azure.net的资源密钥,作为对https://login.microsoftonline.com/ {ActiveDirectoryId} / oauth2的api调用的请求主体/令牌。
答案 5 :(得分:0)
重要提示
由azure为JWT令牌生成的“ aud”值也由AD应用程序清单中的“ accessTokenAcceptedVersion”属性控制。
此属性定义了将生成的访问令牌的版本(MS docs about accessTokenAcceptedVersion)。
可能的结果: