"authentication failed due to: jwt audience is invalid" 使用 Azure AD

"authentication failed due to: jwt audience is invalid" with Azure AD

首先我将描述我如何设置我的应用程序,然后我将描述我如何使用 APIs。

设置

  1. 在我的 Azure Active Directory 中,我注册了两个应用程序:UI 和后端
  2. UI 具有客户端 ID clientId1,后端具有客户端 ID clientId2(它是一个 GUID,但为了简单起见)
  3. 两者都属于同一个租户tentant1(单租户)

后端(Web API)

  1. 后端有一个公开的 API 范围 "api://clientId2/access_as_user" 和授权客户端 "clientId1" 刚刚提到的范围已选择
  2. 我正在使用 passportpassport-azure-ad(我几乎复制了 https://github.com/Azure-Samples/active-directory-javascript-nodejs-webapi-v2)。
  3. 我的配置:

    const config = {
        identityMetadata: "https://login.microsoftonline.com/tenant1/v2.0/.well-known/openid-configuration",
        clientID: "clientId2",
        validateIssuer: false,
        loggingLevel: 'info',
        passReqToCallback: false,
        loggingNoPII: false
    };
    
  4. 我在启动服务器时收到此消息:
{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":16052,"level":40,"msg":"Production environments should always validate the issuer.","time":"2020-04-11T13:25:44.283Z","v":0}
{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":16052,"level":30,"msg":"In BearerStrategy constructor: created strategy with options {\"identityMetadata\":\"https://login.microsoftonline.com/tenant1/v2.0/.well-known/openid-configuration\",\"clientID\":\"clientId2\",\"validateIssuer\":false,\"loggingLevel\":\"info\",\"passReqToCallback\":false,\"loggingNoPII\":false,\"clockSkew\":300,\"allowMultiAudiencesInToken\":false,\"audience\":[\"clientId2\",\"spn:clientId2\"]\"isB2C\":false,\"_isCommonEndpoint\":false}","time":"2020-04-11T13:25:44.285Z","v":0}
Listening on port 5000

UI(Angular SPA)

  1. UI 有权限被自动授予访问 Microsoft Graph 的权限(个人资料,user.read,user.read.all -- 我想我授予的最后一个)。权限在"API permissions"
  2. 我继续并授予了对后端的访问权限 access_as_user
  3. 对于 UI 代码,我使用的是 MSAL 库,而且我几乎完全复制了存储库 (https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-angular)
  4. protectedResourceMap 字段中我添加了以下内容
 ['https://graph.microsoft.com/v1.0/me', ['user.read']],
 ['http://localhost:5000', ['api://clientId2/access_as_user']],
  1. 我可以登录并阅读我的用户个人资料,但是在尝试访问 http://localhost:5000/hello(受保护)时,我收到错误标题
{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":20720,"level":30,"msg":"authentication failed due to: jwt audience is invalid","time":"2020-04-11T13:38:08.700Z","v":0}

--

我可以看到 Bearer Token 即将到来(在 UI 和后端),服务器解码令牌(我可以在服务器日志中看到我所有的个人资料信息),但它说 JWT 无效?!

我没有定义观众,但我可以在使用 aud: 'api://clientId2'.

解码观众时在令牌中看到

我还可以看到,当后端启动时,它默认将观众显示为 [clientId2, sps:clientId2](后端的第 4 步)。当我在配置 audience: 'api://clientId2' 中定义时,我收到 403 消息:

{"name":"AzureAD: Bearer Strategy","hostname":"DESKTOP-NCVLN56","pid":12644,"level":30,"msg":"In Strategy.prototype.jwtVerify: We did not pass Req back to Callback","time":"2020-04-11T16:19:30.398Z","v":0}

如有任何帮助,我们将不胜感激。谢谢。

原来他们在存储库中的代码没有使用正确的配置来验证范围访问...

https://github.com/Azure-Samples/active-directory-javascript-nodejs-webapi-v2/blob/master/index.js#L41

        if (req.authInfo['scp'].split(" ").indexOf("demo.read") >= 0) {

我需要将范围从 "demo.read" 更改为 "access_as_user"。

在我的例子中,我的应用程序 运行 所在的 VM 的时钟落后了 15 分钟。所以创建令牌的时间是在未来...