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 ID
或 APP 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 - 受众无效的主要内容,如果未能解决你的问题,请参考以下文章
AzureAD JWT 令牌受众声明前缀使 JWT 令牌无效
Microsoft Graph API 身份验证错误:“访问令牌验证失败。无效的受众”