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

时间:2016-08-16 15:00:33

标签: node.js rest jwt adal azure-active-directory

我正在使用'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"
}

2 个答案:

答案 0 :(得分:0)

两年后仍然面临着同样的问题。正如@Adam Young在对自己的问题的评论中所述-用受众URL替换受众ID,这样就可以解决问题。

答案 1 :(得分:0)

似乎是“通过设计” Azure AD的文档 1

在描述响应字段的Azure AD的SAML 2.0 Single Sign-On SAML protocol中,它们描述了受众响应值。请注意底部的粗体文本:

  

受众

     

这包含一个标识目标受众的URI。 Azure AD将此元素的值设置为发起登录的AuthnRequest的Issuer元素的值。要评估受众群体值,请使用在应用程序注册期间指定的应用程序ID URI的值。

     

与Issuer值一样,Audience值必须与表示Azure AD中云服务的服务主体名称之一完全匹配。 但是,如果Issuer元素的值不是URI值,则响应中的Audience值就是以spn:为前缀的Issuer值。

因此,无论好坏,Azure AD SAML 2.0的答案似乎要么是:

  1. 将您的颁发者实体ID更改为URI
  2. 更改您的实现,从受众响应值的开头剥离spn:

1 SAML 2.0 Core spec并不将<Issuer>元素指定为URI,而是将其作为复杂类型NameIDType,即字符串默认情况下没有格式要求。因此,我们可以为Azure AD对非URI字符串感到不满而感到恼火。话虽这么说,规范中的每个示例发卡行<< / strong>是,所以也许我们烦恼的自我辩解有其局限性。