Azure AAD - 受众无效

Posted

技术标签:

【中文标题】Azure AAD - 受众无效【英文标题】:Azure AAD - The audience is invalid 【发布时间】:2017-03-13 04:30:10 【问题描述】:

我创建了一个使用 azure 活动目录保护的 webapi。我现在需要对此进行测试并尝试使用带有授权标头的提琴手。我正在尝试使用以下代码生成令牌。

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 观众无效”

【问题讨论】:

据我所知,您可以将 Audience 配置为由 AD 保护的 Web API 应用程序的 CLIENT IDAPP ID URI。根据您提供的错误,我假设您可以尝试检查 Web API 应用程序中的受众和客户端应用程序中的 ResourceId。 这里有什么解决办法吗?遇到同样的问题。 您需要在请求令牌时传递范围/受众。这是 Microsoft 文档的链接 1.docs.microsoft.com/en-us/azure/active-directory-b2c/… 2.docs.microsoft.com/en-us/azure/storage/common/… 尝试传递 resourceUri 而不是 apiResourceId,如本例 --> docs.microsoft.com/en-us/rest/api/datacatalog/… 【参考方案1】:

我遇到了同样的错误。这是因为我使用的是自定义域,所以我的 API ID URL 不是api://client-id

解决方案是在您的appsettings.json 上设置Audience 设置,就像在the Microsoft Wiki 中提到的那样:

"AzureAd": 
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "XXXXXXXX-XXXXX-XXXXX-XXXXX-XXXXXXXXXX",
    "ClientId" : "XXXXXXXX-XXXXX-XXXXX-XXXXX-XXXXXXXXXX",
    // Audience = Portal.Azure.com > App Registration > Expose an API > "Application ID URI"
    "Audience": "Application ID URI"   

【讨论】:

【参考方案2】:

也可能是您的 app/lib 正在使用更新版本的 api。 如果您的应用程序清单中的 accessTokenAcceptedVersion 为 null,则 ms 默认为 v1。 在http://jwt.io 中检查您的 jwt 令牌 如果你得到这个 - 检查你的 JWT 令牌。如果国际空间站不是这样的

 "iss": "https://login.microsoftonline.com/[yadyada]/v2.0",

那么您很可能正在使用另一个版本(例如默认的版本 1)。检查您的 azure 广告应用的清单: 下面的值可能是 null 或一,应该是二:

"accessTokenAcceptedVersion": 2,

【讨论】:

花了几个小时试图解决这个问题,这就是问题所在。就我而言,accessTokenAcceptedVersion 为空(在 Web API 清单中)。我将它设置为 2(与版本匹配)并且它有效。谢谢! 这解决了我的问题,我还花了几个小时来调查这个问题,当我将该值更改为 2 时,它就可以工作了。我认为问题是 Aad 发布了版本 1 令牌,但您的 MSAL 库只能验证版本 2 令牌,这就是差异。我认为微软文档目前没有引起足够的重视。【参考方案3】:

重要提示

azure 为 JWT 令牌生成的“aud”值也由 AD 应用程序清单中的“accessTokenAcceptedVersion”属性控制。

此属性定义将生成的访问令牌的版本 (MS docs about accessTokenAcceptedVersion)。

其值的可能结果:

null 或 1 - "api://" 附加到 GUID 2 - 没有添加“api://”,所以应该只有 GUID

【讨论】:

【参考方案4】:

问题

在执行这篇Protected web API: Code configuration 文章中的说明后,我收到了类似于 OP 的错误消息:

WWW-Authenticate: Bearer error="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"   

【讨论】:

这对我有所帮助。原来uri是区分大小写的。所以从上面显示的页面复制它解决了我的问题。 这对我也有帮助! Microsoft 的文档和当前的 Blazor wasm 模板无法正确生成 ClientId。来源:docs.microsoft.com/en-us/aspnet/core/blazor/security/… 我已经盯着这个两天了,它也解决了我的问题!【参考方案5】:

在调用api实现服务原理时,通过在活动目录中的App注册。 我在使用不记名密钥调用 api-GET vaultBaseUrl/secrets/secret-name/secret-version?api-version=7.0 以获取密钥库秘密值时收到此错误。 作为修复的一部分,为了获取承载值,除了传递 clientid、client secret、grant_type 之外,我添加了值为 https://vault.azure.net 的资源密钥作为对 https://login.microsoftonline.com/ActiveDirectoryId/oauth2/token 的 api 调用的请求正文的一部分。

【讨论】:

【参考方案6】:

我遇到了同样的问题。当我应该使用服务器的资源 ID 时,我使用客户端的资源 ID 作为 AcquireToken 的参数。

当我使用正确的资源 ID 时它可以工作。

【讨论】:

太棒了!现在我读了你的评论似乎很明显。这现在对我有用。谢谢:)【参考方案7】:

我有同样的问题。想分享一下。我已将 Web Api Audience 更改为 Web App 的 ClientId。之后它就可以工作了。

【讨论】:

你能告诉我你是在哪里做的吗? @Ron16 它在 appsettings.json 中。如果您已将访问令牌接受版本设置为 2,或者对于 Azure AD B2C Web API,则客户端 ID 和受众需要相同(即无需编写 api://)来源:docs.microsoft.com/en-us/azure/active-directory/develop/…【参考方案8】:

我认为重新审视身份验证的不同步骤很重要,希望通过讨论您能够解决您遇到的问题。

当客户端尝试获取资源的访问令牌时,它需要向 AAD 指定它想要获取令牌的资源。一个客户端可能被配置为调用多个资源,所有资源都具有不同的配置,因此期望始终在访问令牌请求中指定资源。

资源可以是资源的 App ID GUID,也可以是在资源上注册的有效 App ID URI。 AAD 应该能够根据您提供的价值唯一地识别您尝试访问的资源。但是,请注意,如果您使用 App ID GUID,您将从 AAD 获得一个令牌,其中 Audience 声明是 App ID GUID。或者,如果您使用 App ID URI,您将看到该 URI 作为令牌中的受众声明。

在这两种情况下,您都会获得“相同”资源的令牌,但令牌中的声明会以不同的方式出现。此外,单个应用程序资源可能在其应用程序上注册了多个 App ID URI。根据您在身份验证请求中使用哪一个,您将在令牌中获得与您传入的资源参数匹配的不同受众声明。

最后,一旦您获得令牌,就将其发送到资源 API,后者将对令牌进行多项验证,例如:客户端 ID 声明、范围/角色声明、身份验证方法 ('acr ' 声称),并且肯定观众声称符合他们的期望!

这意味着资源 API 最终需要说“我接受 作为有效的受众声明”...或“我接受 作为有效的受众声明”。这种逻辑可能内置在您正在使用的库中(如 OWIN),但您需要确保在 API 端,您已为您期望的受众正确配置了它。如果您愿意,您可以让您的 API 根本不检查 Audience 声明!令牌中的所有声明都是纯文本的,因此你真的可以做任何你想做的事,但在这种情况下你不会有一个非常安全的 API :]

一天结束,我的预感是这个错误来自您自己的 API,并且它发生是因为您尚未将您的应用配置为接受与您的资源的应用 ID GUID 匹配的受众声明(它看起来像当您根据您的代码示例获取令牌时,您正在传递)。

希望这能解决你的问题!

【讨论】:

我最近开始学习AAD。这个答案用易于理解和简洁的语言解释了事情,比我读过的几乎所有官方文档都要好。谢谢!

以上是关于Azure AAD - 受众无效的主要内容,如果未能解决你的问题,请参考以下文章

Facebook 受众出价不起作用:捆绑状态无效

AzureAD JWT 令牌受众声明前缀使 JWT 令牌无效

Microsoft Graph API 身份验证错误:“访问令牌验证失败。无效的受众”

Okta 无效令牌

Azure 机器学习在运行管道时抛出错误“无效图:节点中的计算目标无效”

Azure 前门:请求 URI 无效