You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6.0.5自定义UserClaimsPrincipalFactory登录时不生成声明问题

问题分析

当使用AzureAD(OIDC)登录时,ASP.NET Core Identity的UserClaimsPrincipalFactory默认不会被触发——这个工厂是为Identity本地认证流程(如密码登录)设计的,而AzureAD登录由OIDC中间件独立处理,不会走Identity的Claims生成逻辑。

解决方案

你可以通过OIDC中间件的OnTokenValidated事件,手动集成自定义声明逻辑,既可以直接在事件中从数据库获取数据添加声明,也可以复用你已实现的ApplicationUserClaimsFactory。

方法1:直接在OnTokenValidated中添加声明

修改认证配置,在OIDC的配置里添加OnTokenValidated事件处理:

builder.Services.AddAuthentication()
    .AddMicrosoftIdentityWebApp(options =>
    {
        builder.Configuration.Bind("AzureAd", options);
        options.Events.OnTokenValidated = async context =>
        {
            // 获取当前用户的邮箱标识
            var email = context.Principal.FindFirstValue(ClaimTypes.Email);
            
            // 从数据库查询对应的ApplicationUser
            var userManager = context.HttpContext.RequestServices.GetRequiredService<UserManager<ApplicationUser>>();
            var user = await userManager.FindByEmailAsync(email);
            
            if (user != null)
            {
                // 从数据库获取自定义声明数据,示例中直接添加,实际替换为你的业务逻辑
                var identity = (ClaimsIdentity)context.Principal.Identity;
                identity.AddClaim(new Claim("Test", "true"));
                identity.AddClaim(new Claim("name", user.UserName));
                // 可添加更多从数据库读取的声明
            }
        };
    });

方法2:复用自定义的ApplicationUserClaimsFactory

如果想复用已实现的ApplicationUserClaimsFactory,同样在OnTokenValidated中调用它:

builder.Services.AddAuthentication()
    .AddMicrosoftIdentityWebApp(options =>
    {
        builder.Configuration.Bind("AzureAd", options);
        options.Events.OnTokenValidated = async context =>
        {
            var email = context.Principal.FindFirstValue(ClaimTypes.Email);
            var userManager = context.HttpContext.RequestServices.GetRequiredService<UserManager<ApplicationUser>>();
            var user = await userManager.FindByEmailAsync(email);
            
            if (user != null)
            {
                // 获取自定义ClaimsPrincipalFactory实例
                var claimsFactory = context.HttpContext.RequestServices.GetRequiredService<IUserClaimsPrincipalFactory<ApplicationUser>>();
                var customPrincipal = await claimsFactory.CreateAsync(user);
                
                // 将原Principal的身份替换为自定义生成的身份
                context.Principal = customPrincipal;
            }
        };
    });
注意事项
  • 确保AzureAD用户和你的本地ApplicationUser已通过邮箱或其他标识正确关联,否则无法查询到对应的本地用户。
  • 若使用方法2,你之前通过AddClaimsPrincipalFactory<ApplicationUserClaimsFactory>()注册工厂的方式是正确的,无需额外修改。

内容的提问来源于stack exchange,提问作者KasperKyhl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 15:45:36