托管在ASP.NET Core中的Blazor Wasm出现User.Identity.Name为空问题
Blazor Wasm Identity声明缺失问题解决方案
核心原因
ASP.NET Core 自带的 IdentityServer ApiAuthorization 默认配置不会自动将name、email类用户声明注入到ID Token、Access Token中,同时JWT认证默认的声明映射规则也不会把JWT中的name字段映射到User.Identity.Name属性,最终导致出现对应的问题。
需补充的配置步骤
- 后端IdentityServer服务追加Identity资源注册
修改你的IdentityServer注册代码,显式注册标准Identity资源,这类资源默认携带name、email等基础用户声明:
services.AddIdentityServer() .AddApiAuthorization<ApplicationUser, ApplicationDbContext>() .AddIdentityResources();- 后端IdentityServer服务追加Identity资源注册
- 后端JWT认证配置声明映射
调整AddIdentityServerJwt配置,指定name为用户名对应的声明类型:
services.AddAuthentication() .AddIdentityServerJwt(opt => { opt.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { NameClaimType = "name", RoleClaimType = "role" // 如需角色权限可同时配置 }; });- 后端JWT认证配置声明映射
- 后端appsettings.json调整客户端权限配置
找到IdentityServer节点下的Blazor客户端配置,在AllowedScopes中追加openid、profile、email三个标准scope:
"IdentityServer": { "Clients": { "你的Blazor客户端名称": { "Profile": "IdentityServerSPA", "AllowedScopes": [ "openid", "profile", "email", "你的自定义API Scope名称" ] } } }- 后端appsettings.json调整客户端权限配置
- 前端Blazor Wasm调整OIDC配置
修改前端Program.cs中的OIDC认证配置,请求对应的scope同时配置声明映射:
builder.Services.AddOidcAuthentication(opt => { opt.ProviderOptions.Authority = "你的IdentityServer服务地址"; opt.ProviderOptions.ClientId = "你的Blazor客户端ID"; // 追加请求标准scope opt.ProviderOptions.DefaultScopes.Add("openid"); opt.ProviderOptions.DefaultScopes.Add("profile"); opt.ProviderOptions.DefaultScopes.Add("email"); opt.ProviderOptions.DefaultScopes.Add("你的自定义API Scope名称"); // 配置前端用户对象的声明映射 opt.UserOptions.NameClaim = "name"; opt.UserOptions.RoleClaim = "role"; });- 前端Blazor Wasm调整OIDC配置
若完成以上配置后仍然缺少对应声明,可实现自定义
IProfileService主动注入需要的声明:public class CustomProfileService : IProfileService { private readonly UserManager<ApplicationUser> _userManager; public CustomProfileService(UserManager<ApplicationUser> userManager) { _userManager = userManager; } public async Task GetProfileDataAsync(ProfileDataRequestContext context) { var user = await _userManager.GetUserAsync(context.Subject); if (user == null) return; context.IssuedClaims.Add(new Claim("name", user.UserName)); context.IssuedClaims.Add(new Claim("email", user.Email)); } public async Task IsActiveAsync(IsActiveContext context) { var user = await _userManager.GetUserAsync(context.Subject); context.IsActive = user != null; } }之后在后端服务注册中追加配置即可:
services.AddIdentityServer() .AddApiAuthorization<ApplicationUser, ApplicationDbContext>() .AddIdentityResources() .AddProfileService<CustomProfileService>();
内容的提问来源于stack exchange,提问作者David Olejnik
相关产品推荐
相关产品推荐

