.NET 8 Blazor SSR静态应用配置Azure AD B2C Entra ID遇阻求助
.NET 8 Blazor SSR静态应用对接Azure AD B2C配置指南
问题背景
配置.NET 8 Blazor SSR静态应用对接Azure AD B2C时,出现多类错误:
- 未设置
ResponseType: "code"时,提示AADB2C90057: 所提供的应用未配置为允许'OAuth'隐式流,即使勾选ID/访问令牌仍无效 - 添加
ResponseType: "code"后,登录完成提示AADB2C90079: 客户端在兑换机密授权时必须发送client_secret - 添加客户端密钥后,出现
IDX21336: 从令牌端点接收的OpenIdConnectProtocolValidationContext.ProtocolMessage中应同时包含'id_token'和'access_token',无法处理该消息
当前配置:
Program.cs代码
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C"));
appsettings.json配置
"AzureAdB2C": { "Instance": "https://[example].b2clogin.com", "Domain": "[example].onmicrosoft.com", "TenantId": "[my tenant id]", "ClientId": "[my client id]", "ClientCapabilities": [ "cp1" ], "SignUpSignInPolicyId": "B2C_1_signup-signin", //"ResponseType": "code" <== 已注释 }
Azure端应用注册信息
- 平台:Web
- 重定向URI:
https://localhost:7021/signin-oidc - 未勾选访问令牌和ID令牌
正确配置方案
1. Azure AD B2C应用注册调整
- 保持平台为Web,不要切换到SPA
- 重定向URI保留
https://localhost:7021/signin-oidc - 在「身份验证」→「隐式授权和混合流」中,无需勾选ID令牌/访问令牌(使用授权码流,不需要隐式流)
- 进入「证书和机密」→「客户端机密」,新建一个客户端机密并保存其值(后续配置用)
- 在「API权限」中添加
openid、profile权限,并完成管理员同意
2. appsettings.json更新
添加客户端密钥并明确设置响应类型为code:
"AzureAdB2C": { "Instance": "https://[example].b2clogin.com", "Domain": "[example].onmicrosoft.com", "TenantId": "[my tenant id]", "ClientId": "[my client id]", "ClientSecret": "[刚才生成的客户端机密值]", "ClientCapabilities": [ "cp1" ], "SignUpSignInPolicyId": "B2C_1_signup-signin", "ResponseType": "code", "Scopes": ["openid", "profile"] }
3. Program.cs代码优化
调整认证配置,适配授权码流并处理令牌验证逻辑:
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(options => { builder.Configuration.Bind("AzureAdB2C", options); // 明确指定授权码流 options.ResponseType = OpenIdConnectResponseType.Code; // 添加必要的作用域 options.Scope.Add("openid"); options.Scope.Add("profile"); // 调整令牌验证参数,确保核心验证逻辑正常 options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, RequireIdToken = true }; // 自定义授权码接收事件,确保正确兑换令牌 options.Events.OnAuthorizationCodeReceived = async context => { var tokenEndpoint = $"{options.Instance}/{options.Domain}/{options.SignUpSignInPolicyId}/oauth2/v2.0/token"; var tokenClient = new TokenClient(tokenEndpoint, options.ClientId, options.ClientSecret); var tokenResponse = await tokenClient.RequestAuthorizationCodeTokenAsync( context.ProtocolMessage.Code, context.Properties.RedirectUri, new Dictionary<string, string> { { "scope", string.Join(" ", options.Scope) } }); if (tokenResponse.IsError) { throw new InvalidOperationException($"令牌兑换失败: {tokenResponse.Error}"); } // 处理令牌兑换结果 context.HandleCodeRedemption(tokenResponse.AccessToken, tokenResponse.IdentityToken); }; }) .AddCookie(); // 添加Cookie认证以维护用户会话 // 配置授权策略 builder.Services.AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); options.FallbackPolicy = options.DefaultPolicy; }); // 确保中间件顺序正确 app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); // 认证中间件必须在授权之前 app.UseAuthorization(); app.MapRazorComponents<App>() .AddInteractiveServerRenderMode(); // 静态SSR需确保渲染模式配置正确
关键说明
- Blazor SSR属于服务器端托管的Web应用,必须使用授权码流(Authorization Code Flow),这是最安全的认证方式
- 客户端密钥必须配置,因为授权码流需要客户端身份验证
- 错误
IDX21336的核心原因是默认验证逻辑对令牌组合的要求,通过自定义OnAuthorizationCodeReceived事件手动处理令牌兑换,可确保获取到正确的id_token和access_token - 不要切换到SPA平台,Blazor SSR的认证模型与SPA完全不同
内容的提问来源于stack exchange,提问作者user1843640
相关产品推荐
相关产品推荐

