使用 B2C 生成元数据端点时,id_token_hint 参数签名验证失败
Posted
技术标签:
【中文标题】使用 B2C 生成元数据端点时,id_token_hint 参数签名验证失败【英文标题】:id_token_hint parameter failed signature validation when Using B2C to generate the metadata endpoints 【发布时间】:2021-12-11 09:17:03 【问题描述】:我正在尝试使用 Azure B2C 设置类似系统的魔术链接。使用以下示例: 初级: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
作为一个注释,我相信我曾经有过它的工作,但在清理之后我得到了错误:
提供的 id_token_hint 参数签名验证失败。请提供另一个令牌并重试。
我设置的步骤如下:
-
通过 powershell 创建证书并获取指纹以在本地代码中使用
通过 MMC 使用 certmng 导出证书
所有任务/导出/下一步/是,导出私钥
个人信息交换 - PKCS(包括证书路径中的所有证书)(启用证书隐私)
安全(密码)随机生成的 25 个字符密码。
名称:id_token_hint_cert.pfx
浏览 Azure/B2C/身份体验框架/策略键
添加/选项:上传/名称: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>();
这是我的主控制器,我在其中提交表单,创建令牌和链接,然后使用它作为立即运行端点重定向到该链接。 (我知道这不会结束工作,但需要先验证签名,然后才能继续。)
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.Hostthis.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 );
【问题讨论】:
【参考方案1】:位置位置位置。
我正在调整我知道不应该这样做的基本配置文件。当我将更改应用到扩展文件时,一切都开始正常工作。
【讨论】:
以上是关于使用 B2C 生成元数据端点时,id_token_hint 参数签名验证失败的主要内容,如果未能解决你的问题,请参考以下文章
如何强制Azure Active Directory身份验证服务重新发出带有更新声明的id_token?
如何使用 B2C 和 Blazor 获取 JWT 不记名令牌