node.js - AzureAD JWT token 受众声明前缀使 JWT token 无效

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

我正在使用“adal-node”npm 包通过 AzureAD 进行身份验证。一切正常,我得到了一个 token 。

但是,在检查 JWT token 中的“aud”声明时,我看到受众 GUID 以“spn:”为前缀。当我尝试在现有的 Web API 上使用 JWT token 时,我认为这会给我带来问题。当我使用相同的 AzureAD 通过 WebApp 进行身份验证时,“aud”声明没有以“spn:”为前缀,并且我能够调用 WebAPI 上的端点。

任何人都可以阐明这一点吗?这是经过大量的头脑 Storm 后要克服的最后一个障碍。

更新:

使用 npm 包“azure-ad-jwt”来验证带有 AzureAD 的 JWT token ,我一收到它就会给我一个我怀疑是问题所在的错误 - “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 token :

{
    "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"
}

最佳答案

似乎已针对 Azure AD“按设计”1 进行了记录。

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

Audience

This contains a URI that identifies an intended audience. Azure AD sets the value of this element to the value of Issuer element of the AuthnRequest that initiated the sign-on. To evaluate the Audience value, use the value of the App ID URI that was specified during application registration.

Like the Issuer value, the Audience value must exactly match one of the service principal names that represents the cloud service in Azure AD. However, if the value of the Issuer element is not a URI value, the Audience value in the response is the Issuer value prefixed with spn:.

所以无论好坏,Azure AD SAML 2.0 的答案似乎是:

  1. 将您的发行人实体 ID 更改为 URI
  2. 更改您的实现以删除 spn:观众响应值开始。

1 SAML 2.0 Core spec指定 <Issuer>元素不是 URI , 但作为复杂类型 NameIDType ,默认情况下没有格式要求的字符串。所以我们会对 Azure AD 对非 URI 字符串不满意感到恼火。话虽如此,规范中的每个示例 Issuer 都是一个 URI,所以也许我们恼火的 self 辩解有其局限性。

关于node.js - AzureAD JWT token 受众声明前缀使 JWT token 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38978298/

相关文章:

rest - 从 ServiceNow REST API 检索文本状态

java - Spring Boot - Spring Security - InvalidBearerTokenException 错误处理

node.js - Grunt Server 和 WebStorm javascript 调试(和 SpyJS)不工作

node.js - 获取 JSON

python - Django 休息框架没有正确读取 JSON

c# - ASP.NET Core 2.2 中的 Azure AD 身份验证

websocket - 为 WebSocket 连接更新 token 的最佳做法是什么

node.js - 具有多个 api 调用的异步/promise

javascript - 如何获取正在发送的全部数据

c# - 在 asp.net core api 中为复杂类型保持相同的 rest 端点