ASP.NET Core 7中SignInManager.CreateUserPrincipalAsync未设置全部声明
解决ASP.NET Core 7中测试时ClaimsPrincipal缺失自定义声明的问题
问题核心:默认的SignInManager.CreateUserPrincipalAsync只会生成Identity内置的声明,不会自动把你扩展的AppUser属性(如FirstName、LastName)转为声明。运行时的Request.User能拿到这些声明,是因为应用中已经配置了自定义声明映射,但测试环境需要显式确保这个配置生效。
解决步骤
1. 自定义UserClaimsPrincipalFactory
创建一个继承自UserClaimsPrincipalFactory<AppUser>的类,在其中添加自定义属性对应的声明:
public class AppUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<AppUser> { public AppUserClaimsPrincipalFactory( UserManager<AppUser> userManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, optionsAccessor) { } protected override async Task<ClaimsIdentity> GenerateClaimsAsync(AppUser user) { var identity = await base.GenerateClaimsAsync(user); // 添加FirstName对应的GivenName声明 if (!string.IsNullOrWhiteSpace(user.FirstName)) { identity.AddClaim(new Claim(ClaimTypes.GivenName, user.FirstName)); } // 添加LastName对应的Surname声明 if (!string.IsNullOrWhiteSpace(user.LastName)) { identity.AddClaim(new Claim(ClaimTypes.Surname, user.LastName)); } return identity; } }
2. 注册自定义Factory到DI容器
在Program.cs(或Startup.cs)的服务配置中,添加自定义Factory的注册:
services.AddDefaultIdentity<AppUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>() .AddClaimsPrincipalFactory<AppUserClaimsPrincipalFactory>(); // 注册自定义声明工厂
3. 测试中验证效果
现在在测试代码中调用signInManager.CreateUserPrincipalAsync(appUser)时,生成的ClaimsPrincipal就会包含FirstName和LastName对应的声明了。
补充说明
运行时的Request.User能拿到自定义声明,通常是因为ASP.NET Core Identity在登录流程中会使用注册的UserClaimsPrincipalFactory来生成完整的ClaimsPrincipal。而测试中直接调用CreateUserPrincipalAsync时,必须确保这个Factory已经被正确注册到测试用的主机服务中——你提到测试用的_host使用和运行应用相同的配置,所以添加上述注册后,测试环境就能和运行环境保持一致的声明生成逻辑。
内容的提问来源于stack exchange,提问作者Alexander Zeitler
相关产品推荐
相关产品推荐

