使用 Passport.js 的 Azure AD 访问令牌签名无效
Azure AD Invalid Signature of Access Token using Passport.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)
- 然后我将令牌保存在 session 存储中的前端,并将其作为授权 header.
与每个请求一起发送
这是我的 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/
我正在尝试使用 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)
- 然后我将令牌保存在 session 存储中的前端,并将其作为授权 header. 与每个请求一起发送
这是我的 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/