id_token_hint 使用 B2C 生成元数据端点时参数签名验证失败

id_token_hint parameter failed signature validation when Using B2C to generate the metadata endpoints

我正在尝试使用 Azure B2C 设置类似 Magic link 的系统。使用以下示例: 初级:
https://github.com/azure-ad-b2c/samples/tree/master/policies/sign-in-with-magic-link

对于 sing B2C 生成元数据端点: https://github.com/azure-ad-b2c/samples/tree/master/policies/invite#using-b2c-to-generate-the-metadata-endpoints

请注意,我相信我曾经让它工作过,但在清理之后我收到了错误:

The provided id_token_hint parameter failed signature validation. Please provide another token and try again.

我设置的步骤如下:

  1. 通过 powershell 创建证书并获取指纹以在本地代码中使用
  2. 通过MMC使用certmng导出证书
    • 所有任务/导出/下一步/是,导出私钥
    • 个人信息交换 - PKCS(包括证书路径中的所有证书)(启用证书隐私)
  3. 安全(密码)随机生成密码 25 个字符的密码。
  4. 姓名:id_token_hint_cert.pfx
  5. 浏览 Azure / B2C / Identity Experience Framework / Policy keys
    • 添加/选项:上传/名称:IdTokenHintCert/文件上传id_token_hint_cert.pfx/密码:来自设置 3 的密码

这是我尝试过 2 种不同设置的地方。第一个是设置一组自定义策略,以便我可以更新以下声明提供程序以将 issuer_secret 设置为 B2C_1A_IdTokenHintCert

<ClaimsProvider>
  <DisplayName>Token Issuer</DisplayName>
  <TechnicalProfiles>
    <TechnicalProfile Id="JwtIssuer">
      <DisplayName>JWT Issuer</DisplayName>
      <Protocol Name="None" />
      <OutputTokenFormat>JWT</OutputTokenFormat>
      <Metadata>
        <Item Key="client_id">{service:te}</Item>
        <Item Key="issuer_refresh_token_user_identity_claim_type">objectId</Item>
        <Item Key="SendTokenResponseBodyWithJsonNumbers">true</Item>
      </Metadata>
      <CryptographicKeys>
        <Key Id="issuer_secret" StorageReferenceId="B2C_1A_IdTokenHintCert" />
        <Key Id="issuer_refresh_token_key" StorageReferenceId="B2C_1A_TokenEncryptionKeyContainer" />
      </CryptographicKeys>
      <InputClaims />
      <OutputClaims />
    </TechnicalProfile>
  </TechnicalProfiles>
</ClaimsProvider>

这是从 https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/tree/master/LocalAccounts 获取并更新到我的租户的一组政策,但大部分时间都是单独保留的。

我也尝试更改我的主要自定义策略中的 issuer_secret,但输出了相同的错误。

进入我的代码: 这是我创业的重要部分:

public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(
            OpenIdConnectDefaults.AuthenticationScheme
        ).AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C"),"OpenIdConnect", "Cookies",true);

        services.AddControllersWithViews();
        services.AddRazorPages() 
            .AddMicrosoftIdentityUI();

        

        services.AddTransient<IClaimsTransformation, AppClaimsTransformations>();
    }

这是我的家庭控制器,我在其中提交表单、创建令牌和 link,然后将其重定向到 link,将其用作 运行 now 端点。 (我知道这不会结束工作,但需要先验证签名才能继续。)

public class HomeController : Controller
{
    private static Lazy<X509SigningCredentials> SigningCredentials;
    private readonly AppSettingsModel _appSettings;
    private readonly IWebHostEnvironment HostingEnvironment;
    private readonly ILogger<HomeController> _logger;

    // Sample: Inject an instance of an AppSettingsModel class into the constructor of the consuming class, 
    // and let dependency injection handle the rest
    public HomeController(ILogger<HomeController> logger, IOptions<AppSettingsModel> appSettings, IWebHostEnvironment hostingEnvironment)
    {
        _appSettings = appSettings.Value;
        this.HostingEnvironment = hostingEnvironment;
        this._logger = logger;

        // Sample: Load the certificate with a private key (must be pfx file)
        SigningCredentials = new Lazy<X509SigningCredentials>(() =>
        {
            X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            certStore.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection certCollection = certStore.Certificates.Find(
                                        X509FindType.FindByThumbprint,
                                        "***************************************",
                                        false);
            // Get the first cert with the thumb-print
            if (certCollection.Count > 0)
            {
                return new X509SigningCredentials(certCollection[0]);
            }

            throw new Exception("Certificate not found");
        });
    }

    [HttpGet]
    public ActionResult Index(string Name, string email, string phone)
    {

        if (string.IsNullOrEmpty(email))
        {
            ViewData["Message"] = "";
            return View();
        }

        string token = BuildIdToken(Name, email, phone);
        string link = BuildUrl(token);

        
        return Redirect(link);
    }


    private string BuildIdToken(string Name, string email, string phone)
    {
        string issuer = $"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase.Value}/";

        // All parameters send to Azure AD B2C needs to be sent as claims
        IList<System.Security.Claims.Claim> claims = new List<System.Security.Claims.Claim>();
        claims.Add(new System.Security.Claims.Claim("name", Name, System.Security.Claims.ClaimValueTypes.String, issuer));
        claims.Add(new System.Security.Claims.Claim("email", email, System.Security.Claims.ClaimValueTypes.String, issuer));

        if (!string.IsNullOrEmpty(phone))
        {
            claims.Add(new System.Security.Claims.Claim("phone", phone, System.Security.Claims.ClaimValueTypes.String, issuer));
        }

        // Create the token
        JwtSecurityToken token = new JwtSecurityToken(
                issuer,
                "******************************************",
                claims,
                DateTime.Now,
                DateTime.Now.AddDays(7),
                HomeController.SigningCredentials.Value);

        // Get the representation of the signed token
        JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler();

        return jwtHandler.WriteToken(token);
    }

    private string BuildUrl(string token)
    {
        string nonce = Guid.NewGuid().ToString("n");

        return string.Format("https://{0}.b2clogin.com/{0}.onmicrosoft.com/{1}/oauth2/v2.0/authorize?client_id={2}&nonce={4}&redirect_uri={3}&scope=openid&response_type=id_token",
                "myTenant",
                "B2C_1A_SIGNIN_WITH_EMAIL",
                "************************************",
                Uri.EscapeDataString("https://jwt.ms"),
                nonce)
                    + "&id_token_hint=" + token;
    }

   
    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}

}

位置位置位置。

我正在调整我了解到不应该做的基本配置文件。当我将更改应用到扩展文件时,一切都开始正常工作。