Azure AAD - 受众群体无效

时间:2016-10-31 03:42:53

标签: azure asp.net-web-api active-directory azure-active-directory asp.net-core-webapi

我创建了一个用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   观众无效"

6 个答案:

答案 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”。部分。

enter image description here

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)。

可能的结果:

  • 空或1-GUID之前的“ api://”
  • 2-未添加“ api://”,因此应该只有GUID