Azure AD B2C-令牌验证不起作用

mar*_*oss 2 jwt azure-ad-b2c

我想使用Azure AD B2C,但使用它有一些困难。我遇到的一个问题是验证令牌的签名。首先,我想使用jwt.io“手动”验证令牌。

根据Microsoft Docs的要求,验证签名应如下所示:

您的应用程序可以使用JWT标头中的kid声明在JSON文档中选择用于签署特定令牌的公钥。然后,它可以使用正确的公钥和指示的算法执行签名验证。

我的理解:从头中获取kid值,在jwks_uri位置下的元数据中查找键,(假设)使用值“ n”来验证签名。

在此处输入图片说明

但是Jwt.io,jsonwebtoken.io和jose-jwt都说,siganture 是无效的。

我想念什么?

anA*_*ent 6

现在有一种方法可以使用两个 npm 包来验证令牌。

资源

该信息可在以下位置获取:Microsoft - Example-verifying-validation-tokens

使用的软件包版本

如何

下面的示例是根据Microsoft 中的示例修改的 - Example-verifying-validation-tokens

从 Azure 检索“颁发者”和“用户流”名称值

Azure 门户的屏幕截图

检索应用程序 ID

在此输入图像描述

代码示例

import jwt from 'jsonwebtoken';
import jkwsClient from 'jwks-rsa';

// Variables that need to be defined based on your Azure B2C Configuration.
const jwksUri = 'https://MY-B2C-TENANT.b2clogin.com/MY-B2C-TENANT.onmicrosoft.com/MY-USER-FLOW-NAME/discovery/v2.0/keys';

const client = jkwsClient({
  jwksUri
});

export function getKey(header, callback) {
  client.getSigningKey(header.kid, (err, key) => {
    var signingKey = key.getPublicKey();
    callback(null, signingKey);
  });
}

export function isTokenValid(token, applicationId, issuerUri) {
  return new Promise((resolve) => {
    const options = {
      audience: [applicationId],
      issuer: [issuerUri]
    };
    jwt.verify(token, getKey, options, (err, decoded) => {
      if (err) {
        // eslint-disable-next-line no-console
        console.error('Jwt Validation Failed', err);
        resolve(false);
      } else {
        // eslint-disable-next-line no-console        
        console.debug(decoded)
        resolve(true);
      }
    });
  });
}

Run Code Online (Sandbox Code Playgroud)

用法

const applicationId = 'APPLICATION ID OF B2C TENANT'
const issuerUri = 'In the User Flow Properties'

const valid = isTokenValid('some token value without "Bearer", applicationId, issuerUri);

Run Code Online (Sandbox Code Playgroud)

笔记

  • 包含jwksUri用户“用户策略”。如果您有多个“用户策略”,您将需要弄清楚如何根据每个“用户策略”流程jkwsClient正确实例化。jwksUri
  • 虽然您可以利用jwt.iojwt.ms,但可以在调试器控制台中对令牌进行解码。这将为您提供一些关键信息,例如“iss”(发行人)和“kid”:
'e3R5cDogIkpXVCIsIGFsZzogIlJTMjU2Iiwga2lkOiAiWU9VX1NORUFLWV9SQUJCSVQifQ==.e2V4cDogMTU5NjYwMTc4NiwgbmJmOiAxNTk2NTk4MTg2LCB2ZXI6ICIxLjAiLCBpc3M6ICJodHRwczovL3doaXRlLXJhYmJpdC5iMmNsb2dpbi5jb20vZjIzNDZhMzBhLTk1ODEtNGU0ZC04MWQwLWQyZjk4NTQ3MWJhOS92Mi4wLyIsIHN1YjogImYzMmNjNmJhLWE5MTctNGE1Ni1hYjhmLWIyNGZmMTg1ODUyOCIsICIuLi4iOiAibW9yZSB2YWx1ZXMuLi4ifQ==.UNODECODEME'.split('.').map((value, index) => { 
   // The signature can't be decoded
   if(index > 1) { return value; }
     return atob(value);
   });

Run Code Online (Sandbox Code Playgroud)


Sac*_*aca 5

Jwt.io似乎仅支持带字符串秘密的HS265和带字符串秘密或证书的RS256

Azure AD B2C使用更原始的RS256形式,根据RFC 3447,第3.1节定义公钥由两个组件组成:ne。该JWK同时包含n并且e可以用来生成公钥和验证令牌签名。

为了使用Jwt.io,您需要将密钥的Azure AD B2C的n + e格式转换为cert格式。请参见以下示例,以获取有关如何执行此操作的参考:转到语言将模量指数转换为X.509证书

  • 就是这样!感谢您为我指明了正确的方向。我终于能够将模数和指数转换为 PEM 格式 [使用 c#](/sf/ask/1988482191/ Correct/28407693#28407693)并能够使用 jwt.io 和 c# 验证签名。 (2认同)