添加自定义声明在 asp.net 核心身份中不起作用

Adding custom claim not working in asp.net core identity

我创建了 CustomClaimType 来存储 user id:

public static class CustomClaimTypes
{
    public const string UserId = "UserId";
}

用户登录时,我设置为:

var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, doc_session.ufname + " " + doc_session.ulname));
claims.Add(new Claim(CustomClaimTypes.UserId, doc_session.isci_id.Value.ToString()));
ClaimsIdentity userIdentity = new ClaimsIdentity(claims,"Identity.Application");
ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);

我还创建了自定义身份扩展:

public static class IdentityExtensions
{
    public static int GetUserId(this IIdentity identity)
    {
        ClaimsIdentity claimsIdentity = identity as ClaimsIdentity;
        Claim claim = claimsIdentity?.FindFirst(CustomClaimTypes.UserId);

        if (claim == null)
            return 0;

        return int.Parse(claim.Value);
    }

    public static string GetName(this IIdentity identity)
    {
        ClaimsIdentity claimsIdentity = identity as ClaimsIdentity;
        Claim claim = claimsIdentity?.FindFirst(ClaimTypes.Name);

        return claim?.Value ?? string.Empty;
    }
}

但是当我调用 User.Identity.GetUserId(); 时,结果是 0(空)。

要向身份添加额外声明,您可以实施自定义 CustomClaimsPrincipalFactory

  1. CustomClaimsPrincipalFactory

    public class CustomClaimsPrincipalFactory : UserClaimsPrincipalFactory<IdentityUser<int>>
    {
        public CustomClaimsPrincipalFactory(UserManager<IdentityUser<int>> userManager,
                                                IOptions<IdentityOptions> optionsAccessor)
        : base(userManager, optionsAccessor)
        {
        }
    
        public async override Task<ClaimsPrincipal> CreateAsync(IdentityUser<int> user)
        {
            var principal = await base.CreateAsync(user);
    
            // Add your claims here
            ((ClaimsIdentity)principal.Identity).AddClaims(
                new[] { new Claim(ClaimTypes.Name, user.UserName),
                new Claim(CustomClaimTypes.UserId, user.Id.ToString())
                });
    
            return principal;
        }
    }
    
  2. 注册CustomClaimsPrincipalFactory

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });
    
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser<int>>()
            .AddEntityFrameworkStores<ApplicationDbContext>();
        services.AddScoped<IUserClaimsPrincipalFactory<IdentityUser<int>>, CustomClaimsPrincipalFactory>();
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }
    
  3. IdentityExtensions

    public static class IdentityExtensions
    {
        public static int GetUserId(this ClaimsPrincipal identity)
        {
            Claim claim = identity?.FindFirst(CustomClaimTypes.UserId);
    
            if (claim == null)
                return 0;
    
            return int.Parse(claim.Value);
        }
    
        public static string GetName(this ClaimsPrincipal identity)
        {
            Claim claim = identity?.FindFirst(ClaimTypes.Name);
    
            return claim?.Value ?? string.Empty;
        }
    }
    
  4. 用法

    public IActionResult About()
    {
        var claims = User.Claims;
        var userId = User.GetUserId();
        var userName = User.GetName();
        ViewData["Message"] = "Your application description page.";
    
        return View();
    }