如何在对接Azure AD的Blazor Server + .NET Web API项目中使用Azure AppRoles
解决方案
现有配置的核心问题
你当前的配置存在两处明显错误,是导致[Authorize(Roles = "xxx")]无法生效的直接原因:
TokenValidationParameters.RoleClaimType的配置逻辑完全错误:该参数用于指定令牌中存储角色列表的声明字段名,而非你需要校验的具体角色值。你先后将其赋值为"admin"、"doku",最终只会生效最后一次的"doku",框架自然无法正确读取到角色信息。- Azure AD 颁发的包含App Roles的令牌中,角色列表默认存储在
roles声明字段中,你没有正确指向该字段。
完整适配方案
1. Web API端配置
首先修改你的Program.cs身份验证配置:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(options => { builder.Configuration.Bind("AzureAd", options); // 指定角色声明字段为Azure AD默认的roles options.TokenValidationParameters.RoleClaimType = "roles"; }, options => { builder.Configuration.Bind("AzureAd", options); });
配置完成后,控制器可以直接使用[Authorize(Roles = "Admin")]、[Authorize(Roles = "Admin,doku")]注解完成权限校验,不需要手动遍历身份信息,你之前写的遍历逻辑可以完全删除。
2. Blazor Server端配置(用于调用Web API时传递令牌)
Blazor Server属于服务端运行场景,调用你的Web API时需要主动获取当前用户的访问令牌并附加到请求头:
- 先安装
Microsoft.Identity.Web、Microsoft.Identity.Web.UINuGet包,确保版本适配你的.NET 5/6环境。 - Blazor Server的Program.cs配置如下:
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration, "AzureAd") // 启用令牌获取能力,用于调用下游Web API,替换为你API暴露的Scope .EnableTokenAcquisitionToCallDownstreamApi(new string[] { "api://<你的Web API客户端ID>/access_as_user" }) // 启用内存令牌缓存(生产环境可替换为分布式缓存) .AddInMemoryTokenCaches(); // 注册用于调用API的HttpClient builder.Services.AddHttpClient<YourApiService>(client => { client.BaseAddress = new Uri("<你的Web API地址>"); });
- 在Blazor Server的服务/页面中调用API时,先通过
ITokenAcquisition获取访问令牌,再附加到请求头:
public class YourApiService { private readonly HttpClient _httpClient; private readonly ITokenAcquisition _tokenAcquisition; public YourApiService(HttpClient httpClient, ITokenAcquisition tokenAcquisition) { _httpClient = httpClient; _tokenAcquisition = tokenAcquisition; } public async Task<string> GetProtectedDataAsync() { // 获取访问令牌 var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] { "api://<你的Web API客户端ID>/access_as_user" }); // 附加Bearer令牌到请求头 _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); return await _httpClient.GetStringAsync("protected/endpoint"); } }
校验确认项
如果配置后仍不生效,请按以下顺序排查:
- 解析你拿到的Web API访问令牌,确认
roles字段已存在且包含分配给用户的角色值 - 确认你在Azure AD中定义App Roles时,
allowedMemberTypes包含了User - 确认API应用注册的清单中
accessTokenAcceptedVersion设置为2 - 确认你已在企业应用中对相应用户/用户组分配了对应的App Roles
内容的提问来源于stack exchange,提问作者daru
相关产品推荐
相关产品推荐

