使用Passport.js的访问令牌的Azure AD无效签名

时间:2020-10-06 14:24:59

标签: node.js azure vue.js passport-azure-ad

我正在尝试使用“护照-天蓝色-广告”策略使用Azure AD B2B为我的NodeJS / VueJS应用设置身份验证。我使用授权码流来获取access_token和id_token。当我将access_token传递给passport-azure-ad策略时,就会出现问题。我收到一个错误消息,说令牌具有无效的签名(jwt.io表示相同)。如果我使用id_token,那么一切正常。但是,我不想使用id_token,因为我想实现无提示刷新,而我只能使用access_token来做到这一点。

这是我的设置:

  • 我有一个VueJS应用程序(以Node.js作为后端),我想使用AAD B2B作为登录名
  • 在前端,我首先进行重定向:
let url = 'https://login.microsoftonline.com/'+TENANT_ID+'/oauth2/v2.0/authorize?'+
    'client_id='+CLIENT_ID+
    '&response_type=code'+
    '&scope=openid offline_access'+
    '&redirect_uri='+window.location.origin+
    '&state='+encodeURIComponent(generateRandomString())+
    '&nonce='+nonce;
  • 然后我将代码发送到我的后端,以将其与此请求交换为令牌:
let data = {
    client_id: CLIENT_ID,
    client_secret: CLIENT_SECRET,
    grant_type: 'authorization_code',
    redirect_uri: window.location.origin,
    code: code
  }
let response = await axios.post(`/${process.env.TENANT}/oauth2/v2.0/token`, data)
  • 然后,我将令牌保存在会话存储的前端中,并将其与每个请求一起作为授权标头发送。

这是我的BearerStrategy的配置:

let options = {
    identityMetadata: "https://login.microsoftonline.com/"+envVars.TENANT+"/v2.0/.well-known/openid-configuration",
    clientID: envVars.CLIENT_ID,
    passReqToCallback: false,
    audience: envVars.CLIENT_ID,
    validateIssuer: true,
    issuer: 'https://sts.windows.net/'+envVars.TENANT+'/',
    loggingLevel: 'error',
}
var bearerStrategy = new OIDCBearerStrategy(options,
  function(token, done) {
    console.log(token)
    if (!token.oid) {
      return done(new Error('oid is not found in token'));
    }
    else {
      return done(null, token.unique_name, token);
    }
  }
);

passport.use(bearerStrategy);

我认为问题是由于某种原因,我重新获得了v1令牌而不是v2。我尝试在应用程序注册清单中设置"accessTokenAcceptedVersion": 2,但无效。

我在做什么错了?

这是解码的令牌,其中隐藏了一些信息:

HEADER:ALGORITHM & TOKEN TYPE
{
  "typ": "JWT",
  "nonce": "1BaxlG05CpKz_zLXaJjZ0-nyYqLpMkktzvL9WiOEL74",
  "alg": "RS256",
  "x5t": "kg2LYs2T0CTjIfj4rt6JIynen38",
  "kid": "kg2LYs2T0CTjIfj4rt6JIynen38"
}

PAYLOAD:DATA
{
  "aud": "00000003-0000-0000-c000-000000000000",
  "iss": "https://sts.windows.net/[tenant_id]/",
  "iat": 1601568985,
  "nbf": 1601568985,
  "exp": 1601572885,
  "acct": 0,
  "acr": "1",
  "aio": "ASQA2/8RAAAAq7Z5bMg6AIJJ25iq7RI34DjbdRD9C6vnTlL3ZeilylQ=",
  "amr": [
    "pwd"
  ],
  "app_displayname": "[app_displayname]",
  "appid": "[appid]",
  "appidacr": "1",
  "family_name": "[family_name]",
  "given_name": "[given_name]",
  "idtyp": "user",
  "ipaddr": "[ipaddr]",
  "name": "[name]",
  "oid": "[oid]",
  "platf": "5",
  "puid": "10033FFFAFA83EAE",
  "rh": "0.ATAAdcJAG5J6AkqwgY-6rF6WssXSwci23txClbKekzYO8PwwAE8.",
  "scp": "User.Read profile openid email",
  "sub": "44PNYdl91SJrrrj4F25e1hXFyj3uTt-1ko6bUyT_Gq8",
  "tenant_region_scope": "EU",
  "tid": "[tenant_id]",
  "unique_name": "[email_address]",
  "upn": "[email_address]",
  "uti": "DNAFrnHtrU6wprPVywDNAA",
  "ver": "1.0",
  "wids": [
    "b79fbf4d-3ef9-4689-8143-76b194e85509"
  ],
  "xms_st": {
    "sub": "xpu87pTRk0UTZGgL9MGwrwTtZXP7qn7Aw-byR3_N_fU"
  },
  "xms_tcdt": 1504270371
}

更新: 原来,我获得了MS Graph API的令牌,但我无法将其用于自己的API。因此,我必须公开我的应用程序的API并将其添加到AAD的权限中。对于这种情况,这是一个非常好的教程-> https://authguidance.com/2017/12/01/azure-ad-spa-code-sample/

1 个答案:

答案 0 :(得分:0)

根据您提供的信息,我们请求访问令牌以调用Microsoft Graph。如果是这样,我们不需要验证Microsoft图形签名。因为MsGraph意识到有机会提高用户的安全性。他们通过在jwt标头中添加“ nonce”来实现此目的。 JWS用现成的SHA2签名,nonce在JWS序列化之前被替换。要验证此令牌,将需要在标头中将nonce的SHA2替换为nonce的SHA2。现在,由于没有公共合同,这种情况可以改变。因此,在调用Microsoft Graph时,应将访问令牌视为不透明。有关更多详细信息,请参阅herehere