Blazor WASM独立应用调用AAD B2C认证的ASP.NET Core 6 Web API遇401问题
核心排查与解决方案
一、验证令牌的受众与作用域匹配
先获取Blazor端的访问令牌(浏览器F12→Application→LocalStorage→oidc.user条目,解码JWT),重点检查:
aud字段必须和Web API的AAD B2C应用ID完全一致,不能是UI应用的IDscp字段必须包含API定义的自定义作用域(例如https://yourtenant.onmicrosoft.com/api/access_as_user)
二、修正Web API的认证配置
- appsettings.json 确保
AzureAdB2C配置明确指定API的受众:
"AzureAdB2C": { "Instance": "https://yourtenant.b2clogin.com/", "Domain": "yourtenant.onmicrosoft.com", "ClientId": "API_APP_ID", "SignUpSignInPolicyId": "B2C_1_signupsignin", "Audience": "API_APP_ID" // 必须设置,否则API会默认验证受众为自身ClientId,需和令牌aud匹配 }
- Program.cs 确认认证中间件顺序正确:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C")); // 中间件顺序不能错:先认证,再授权 app.UseAuthentication(); app.UseAuthorization();
三、Blazor WASM端的令牌传递配置
- appsettings.json 确保
Scopes包含API的作用域:
"AzureAdB2C": { "Authority": "https://yourtenant.b2clogin.com/yourtenant.onmicrosoft.com/B2C_1_signupsignin", "ClientId": "UI_APP_ID", "ValidateAuthority": true, "Scopes": [ "openid", "profile", "https://yourtenant.onmicrosoft.com/api/access_as_user" // 必须包含API的作用域 ] }
- Program.cs 注册带自动令牌附加的HttpClient,并关联NSWAG客户端:
// 注册带令牌处理的HttpClient builder.Services.AddHttpClient("ApiClient", client => { client.BaseAddress = new Uri("https://your-api-base-url/"); }) .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>(); // 绑定NSWAG生成的客户端到该HttpClient builder.Services.AddScoped<IApiClient>(sp => { var httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient("ApiClient"); return new ApiClient(httpClient); }); // 配置MSAL认证,默认令牌包含API作用域 builder.Services.AddMsalAuthentication(options => { builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication); options.ProviderOptions.DefaultAccessTokenScopes.Add("https://yourtenant.onmicrosoft.com/api/access_as_user"); });
- 页面/服务中使用客户端 直接注入配置好的
IApiClient,无需手动处理令牌,BaseAddressAuthorizationMessageHandler会自动将有效访问令牌附加到请求头:
// 页面示例 @inject IApiClient ApiClient private async Task LoadData() { try { var data = await ApiClient.GetYourDataAsync(); // 处理返回数据 } catch (ApiException ex) { // 处理API错误 } }
四、额外验证步骤
- 用Postman测试:通过B2C授权码流获取UI的访问令牌,调用API时添加
Authorization: Bearer {token}请求头,若仍返回401,说明令牌本身或API配置有问题;若请求成功,说明Blazor端的令牌传递逻辑需调整 - 开启API认证日志排查具体失败原因:
builder.Logging.AddConsole(); builder.Services.AddLogging(logging => { logging.AddFilter("Microsoft.AspNetCore.Authentication", LogLevel.Debug); });
内容的提问来源于stack exchange,提问作者kingua
相关产品推荐
相关产品推荐

