验证Azure广告访问令牌时签名无效,但ID令牌有效

时间:2017-07-26 03:54:14

标签: validation oauth-2.0 azure-active-directory access-token adal

使用jwt.io验证我的azure广告访问令牌时,我的签名无效。但是,我的身份令牌验证就好了!

我已经看过并试过了建议的解决方案 Invalid signature while validating Azure ad access token

https://nicksnettravels.builttoroam.com/post/2017/01/24/Verifying-Azure-Active-Directory-JWT-Tokens.aspx
但不适用于我的访问令牌。

访问和Id令牌通过Adal.js生成:

    var endpoints = {
        "https://graph.windows.net": "https://graph.windows.net"
    };
    var configOptions = {
        tenant: "<ad>.onmicrosoft.com", // Optional by default, it sends common
        clientId: "<app ID from azure portal>",
        postLogoutRedirectUri: window.location.origin,
        endpoints: endpoints,
    }
    window.authContext = new AuthenticationContext(configOptions);

为什么我可以验证我的ID令牌,但不能验证我的访问令牌?

3 个答案:

答案 0 :(得分:4)

请参阅主题:https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/609

  
    

但是如果看看Jwt.Header,你会看到一个'nonce'。这意味着您需要特殊处理。正常处理将失败。

  

因此,如果nonce包含在访问令牌中,则使用JWT.io或JwtSecurityToken验证签名将不会成功。

答案 1 :(得分:0)

如果其他人有无效签名错误,您应该检查此评论:https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/521#issuecomment-577400515

解决了我的配置问题。

本质上,如果您要获取访问令牌来访问自己的资源服务器而不是图谱 API,则范围参数应为 [CLIENT_ID]/.default(如果您使用访问令牌来访问图谱 API,则不不需要自己验证令牌)

答案 2 :(得分:0)

感谢@Antoine,我修复了我的代码。在这里,我将让我的个人 vue.js 插件供其他人参考:

import { PublicClientApplication } from '@azure/msal-browser'
import { Notify } from 'quasar'

export class MsalService {
  _msal = null
  _store = null
  _loginRequest = null

  constructor (appConfig, store) {
    this._store = store
    this._msal = new PublicClientApplication(
      {
        auth: {
          clientId: appConfig.auth.clientId,
          authority: appConfig.auth.authority
        },
        cache: {
          cacheLocation: 'localStorage'
        }
      })

    this._loginRequest = {
      scopes: [`${appConfig.auth.clientId}/.default`]
    }
  }

  async handleResponse (response) {
    await this._store.dispatch('auth/setResponse', response)
    const accounts = this._msal.getAllAccounts()
    await this._store.dispatch('auth/setAccounts', accounts)

    if (accounts.length > 0) {
      this._msal.setActiveAccount(accounts[0])
      this._msal.acquireTokenSilent(this._loginRequest).then(async (accessTokenResponse) => {
        // Acquire token silent success
        // Call API with token
        // let accessToken = accessTokenResponse.accessToken;
        await this._store.dispatch('auth/setResponse', accessTokenResponse)
      }).catch((error) => {
        Notify.create({
          message: JSON.stringify(error),
          color: 'red'
        })
        // Acquire token silent failure, and send an interactive request
        if (error.errorMessage.indexOf('interaction_required') !== -1) {
          this._msal.acquireTokenPopup(this._loginRequest).then(async (accessTokenResponse) => {
            // Acquire token interactive success
            await this._store.dispatch('auth/setResponse', accessTokenResponse)
          }).catch((error) => {
            // Acquire token interactive failure
            Notify.create({
              message: JSON.stringify(error),
              color: 'red'
            })
          })
        }
      })
    }
  }

  async login () {
    // this._msal.handleRedirectPromise().then((res) => this.handleResponse(res))
    // await this._msal.loginRedirect(this._loginRequest)
    await this._msal.loginPopup(this._loginRequest).then((resp) => this.handleResponse(resp))
  }

  async logout () {
    await this._store.dispatch('auth/setAccounts', [])
    await this._msal.logout()
  }
}

// "async" is optional;
// more info on params: https://quasar.dev/quasar-cli/boot-files
export default ({
  app,
  store,
  Vue
}) => {
  const msalInstance = new MsalService(
    app.appConfig, store
  )
  Vue.prototype.$msal = msalInstance
  app.msal = msalInstance
}

PD:使用类星体框架