Blazor WebAssembly调用受Microsoft Identity保护的外部API遇401未授权
排查Blazor WebAssembly调用外部Azure AD保护API返回401的问题
以下是你可能遗漏的关键配置项,按优先级逐一排查:
1. 补全Blazor WASM应用注册的API权限配置
在Azure门户中,为Blazor WASM的应用注册添加外部API的委托权限并完成管理员授权:
- 进入Blazor WASM应用注册页面 → 「API权限」→ 「添加权限」→ 选择你的外部API(
api://d3de6da4-xxx) - 添加
User.Read权限(与外部API控制器要求的范围一致) - 点击「授予管理员同意」(必须完成此步骤,否则用户登录后无法获取该权限的访问令牌)
2. 修正MiddletierApiAuthorizationMessageHandler的授权URL
当前消息处理器中配置的authorizedUrls是https://localhost:7575,与外部API的实际地址https://localhost:50441不匹配,导致不会为目标API附加令牌。修改为:
public class MiddletierApiAuthorizationMessageHandler : AuthorizationMessageHandler { public MiddletierApiAuthorizationMessageHandler(IAccessTokenProvider provider, NavigationManager navigationManager) : base(provider, navigationManager) { ConfigureHandler( authorizedUrls: new[] { "https://localhost:50441" }, // 替换为外部API的Base地址 scopes: new[] { "api://d3de6da4-xxx/User.Read" }); } }
3. 在AddMsalAuthentication中添加外部API的范围
当前仅配置了服务器项目API的范围,需将外部API的User.Read范围加入默认请求范围,确保登录时获取对应权限的令牌:
builder.Services.AddMsalAuthentication(options => { builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication); // 保留原有服务器API范围,新增外部API范围 options.ProviderOptions .DefaultAccessTokenScopes .Add("api://544b368d-xxx/user.access"); options.ProviderOptions .DefaultAccessTokenScopes .Add("api://d3de6da4-xxx/User.Read"); });
4. 验证外部API的Azure AD配置
确保外部API的appsettings.json中AzureAd配置的参数正确:
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "你的租户ID", "ClientId": "d3de6da4-xxx", // 外部API的应用注册ID "Scopes": "User.Read" }
5. 检查访问令牌的受众与范围
在浏览器开发者工具的「Application」→「Local Storage」中找到MSAL存储的令牌,用JWT解码工具验证:
aud(受众)必须等于外部API的应用ID URI(api://d3de6da4-xxx)scp(范围)必须包含User.Read
6. 确认CORS配置的完整性
确保外部API的CORS策略允许Blazor WASM的地址,且开启凭据携带:
builder.Services.AddCors(options => { options.AddPolicy("AllowBlazorApp", policy => { policy.WithOrigins("https://localhost:你的Blazor端口") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); // 必须开启,否则令牌无法携带 }); }); // 在管道中启用CORS(放在UseRouting之后,UseAuthorization之前) app.UseCors("AllowBlazorApp");
内容的提问来源于stack exchange,提问作者Enrico
相关产品推荐
相关产品推荐

