AzureAD JWT 令牌受众声明前缀使 JWT 令牌无效
Posted
技术标签:
【中文标题】AzureAD JWT 令牌受众声明前缀使 JWT 令牌无效【英文标题】:AzureAD JWT Token Audience claim prefix makes JWT Token invalid 【发布时间】:2016-12-23 00:42:08 【问题描述】:我正在使用“adal-node”npm 包向 AzureAD 进行身份验证。这一切都很好,我得到了一个令牌。
但是,在检查 JWT 令牌中的“aud”声明时,我看到受众 GUID 以“spn:”为前缀。当我尝试在已经存在的 Web API 上使用 JWT 令牌时,我认为这会给我带来问题。当我使用相同的 AzureAD 通过 WebApp 进行身份验证时,“aud”声明不以“spn:”为前缀,并且我可以在 WebAPI 上调用端点。
任何人都可以对此有所了解吗?这是在费了很多脑筋之后才能克服的最后一道障碍。
更新:
使用 npm 包“azure-ad-jwt”通过 AzureAD 验证 JWT 令牌后,我收到了我怀疑是问题的错误 - “JWT 受众无效”。它期望“aud”声明没有“spn:”前缀。这个 spn 前缀是从哪里来的?
这是我的 app.js
var adal = require('adal-node');
var activeDirectoryEndpointUrl = 'https://login.microsoftonline.com/';
var options =
domain: '<AzureAD GUID>',
activeDirectoryResourceId: '<AzureAD App Client ID 1>',
clientId: '<AzureAD App Client ID 2>'
;
var tokenCache = new adal.MemoryCache();
var authorityUrl = activeDirectoryEndpointUrl + options.domain;
var context = new adal.AuthenticationContext(authorityUrl, true, tokenCache);
context.acquireUserCode(options.activeDirectoryResourceId, options.clientId, 'en-us', function (err, userCodeResponse)
if (err)
console.error(err);
return;
console.log('Use a web browser to open the page ' + userCodeResponse.verificationUrl + ' and enter the code ' + userCodeResponse.userCode + ' to sign in.');
context.acquireTokenWithDeviceCode(options.activeDirectoryResourceId, options.clientId, userCodeResponse, function (err, tokenResponse)
if (err)
console.error(err);
return;
console.log(tokenResponse);
);
);
解码的 JWT 令牌:
"typ":"JWT",
"alg":"RS256",
"x5t":"XXXXXXX",
"kid":"XXXXXXX"
"aud":"spn:XXXXXXX", // <<< Offending claim
"iss":"https://sts.windows.net/XXXXXXX/",
"iat":1471355868,
"nbf":1471355868,
"exp":1471359768,
"acr":"1",
"amr":["pwd"],
"appid":"XXXXXXX",
"appidacr":"0",
"e_exp":7200,
"family_name":"XX",
"given_name":"XX",
"ipaddr":"XX.XX.XX.XX",
"name":"XX XX",
"oid":"XXXXXXX",
"scp":"user_impersonation",
"sub":"XXXXXXX",
"tid":"XXXXXXX",
"unique_name":"XXX@XXX.onmicrosoft.com",
"upn":"XXX@XXX.onmicrosoft.com",
"ver":"1.0"
【问题讨论】:
这个问题你解决了吗? 在向 Microsoft 提出支持请求后,他们确认问题出在 adal npm 包上。它使用的 AzureAD api 版本旧且需要更新。他们什么时候会更新 npm 包,我不确定。或者,他们建议对受众使用 URI,而不是 GUID。 请建议替换 npm (adal-node 似乎已被废弃 【参考方案1】:2 年后仍然面临同样的问题。正如@Adam Young 在 cmets 中针对他自己的问题发布的那样 - 将受众 ID 替换为受众 URL,这将解决问题。
【讨论】:
【参考方案2】:似乎按“设计”1 记录在 Azure AD 中。
在描述响应字段的 Azure AD 的 SAML 2.0 Single Sign-On SAML protocol 中,它们描述了 audience 响应值。注意底部的粗体文本:
观众
这包含一个标识目标受众的 URI。 Azure AD 将此元素的值设置为启动登录的 AuthnRequest 的 Issuer 元素的值。要评估 Audience 值,请使用在应用程序注册期间指定的 App ID URI 的值。
与 Issuer 值一样,Audience 值必须与代表 Azure AD 中的云服务的服务主体名称之一完全匹配。 但是,如果 Issuer 元素的值不是 URI 值,则响应中的 Audience 值是前缀为
spn:
的 Issuer 值。
因此,无论好坏,Azure AD SAML 2.0 的答案似乎都是:
-
将您的发行人实体 ID 更改为 URI
更改您的实现以从 audience 响应值的开头去除
spn:
。
1SAML 2.0 Core spec 指定<Issuer>
元素不是URI
,而是复杂类型NameIDType
,默认情况下没有格式要求的字符串。因此,我们会对 Azure AD 对非 URI 字符串不满意感到恼火。话虽如此,规范中的每个示例 Issuer都是一个 URI,所以也许我们恼火的自我辩护有其局限性。
【讨论】:
以上是关于AzureAD JWT 令牌受众声明前缀使 JWT 令牌无效的主要内容,如果未能解决你的问题,请参考以下文章
Azure AD 令牌中的哪些 JWT 声明可以安全地用于用户映射?