Search code examples
c#asp.net-coreasp.net-core-mvcasp.net-identity

Adding custom claim not working in asp.net core identity


I have created CustomClaimType to store user id:

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

When user login, I set it:

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);

I have also created custom identity extension:

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;
    }
}

But when I call User.Identity.GetUserId(); I get 0 (null) as result.


Solution

  • For adding extra claims to Identity, you could implement custom 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. Register 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. Useage

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