使用Passport-azure-ad的BearerStrategy结合MSAL出现无效签名错误
客户端基于React.js,使用@azure/msal-react、@azure/msal-browser;服务端基于Express.js,使用passport-azure-ad配置BearerStrategy,代码如下:
var options = { identityMetadata:"https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration", clientID:"<client-id>", validateIssuer:true, issuer: "https://login.microsoftonline.com/<tenant-id>/v2.0", passReqToCallback: false, allowMultiAudiencesInToken: false, audience:"<client-id>", loggingLevel: "info", loggingNoPII: false, scope: ["User.Read"], }; var bearerStrategy = new BearerStrategy(options, function(token, done) { log.info('verifying the user'); log.info(token, 'was the token retreived'); findById(token.oid, function(err, user) { if (err) { return done(err); } if (!user) { // "Auto-registration" log.info('User was added automatically as they were new. Their oid is: ', token.oid); users.push(token); owner = token.oid; return done(null, token); } owner = token.oid; return done(null, user, token); }); } );
收到的错误日志:
{"name":"AzureAD: Bearer Strategy","hostname":"xxxxx-xxxxx","pid":xxxxx,"level":x,"msg":"authentication failed due to: invalid signature","time":"xxxx","v":0}
服务器可从请求头接收accessToken并解析获取用户信息,但生成pemKey后出现上述无效签名错误,请问该错误的原因是什么?
出现"invalid signature"错误,核心是服务端验证token签名时不匹配,常见原因如下:
Token类型或受众不匹配:如果客户端获取的是ID Token而非Access Token,或者拿到的是针对Microsoft Graph的Access Token(受众为
https://graph.microsoft.com),而非你的API专属Access Token,服务端验证签名时会失败。需确认客户端请求的是你API的专属scope,且token的aud字段与服务端配置的audience完全一致。租户ID或Issuer配置错误:检查
identityMetadata和issuer中的<tenant-id>是否为正确的GUID格式,无拼写错误。Azure AD v2.0的issuer格式为https://login.microsoftonline.com/{tenantId}/v2.0,若租户ID错误,服务端获取的公钥与token的签名颁发方不匹配,会导致验证失败。公钥缓存未刷新:
passport-azure-ad会缓存从OpenID配置端点获取的公钥,若公钥已更新但缓存未刷新,会用旧公钥验证新token的签名。可尝试重启服务,或检查是否有强制刷新公钥的配置项。Token签名损坏或被篡改:虽然能解析用户信息,但token的签名部分可能在传输中损坏或被篡改。可解码token确认
alg字段为RS256(Azure AD默认签名算法),同时验证签名是否能与对应公钥匹配。无效配置项干扰:BearerStrategy的
scope配置并非passport-azure-ad的有效参数,多余的配置可能引发内部逻辑异常,建议移除该字段。
内容的提问来源于stack exchange,提问作者Vishal Jaiswal

