Bagzli
Bagzli

Reputation: 6569

Identity Core Get Name & Other fields

I have noticed that with Identity core I can get the name field in the following way:

HttpContext.User.Identity.Name

I don't understand how this value is set and how would I add other fields to it such as MyCustomField or Address or Id. I've been looking over the open source https://github.com/aspnet/Identity however, I just can't seem to figure it out. Ideally, I would like to this outside of the identity project and within my own.

Can somebody explain to me how this works and how I would add more fields?

EDIT:

If I wanted to add Address I would write the following code:

public static class IdentityExtensions
{
     public static string GetAddress(this IIdentity identity)
     {
         return ((ClaimsIdentity) identity).FindFirst("Address").Value;
     }
 }

Now the above code allows me to pull the address value out of the claim, but what I don't understand is how to get the value saved in there.

If I were using EF then I would do that under GenerateUserIdentityAsync method. However, I am not and I'm using dapper, so I'm trying to understand how this work. At what point would I read the information from the database and add it to the claim (I understand that would happen at login, but where in the code would this happen, how is the current Name being filled in)?

Upvotes: 0

Views: 1494

Answers (1)

Newport99
Newport99

Reputation: 483

I accomplished this by doing the following:

1 - Added a new column to [AspNetUsers] table named [staff_id] in the database.

2 - Created an ApplicationUser class that inherits from IdentityUser

public class ApplicationUser : IdentityUser
{
 public ApplicationUser(){ }
 public int staff_id { get; set; }
}

3 - Created a class AppClaimsPrincipalFactory that inherits UserClaimsPrincipalFactory and overrides the CreateAsync method.

public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
    public AppClaimsPrincipalFactory(UserManager<ApplicationUser> userManager,
                                     RoleManager<IdentityRole> roleManager,
                                     IOptions<IdentityOptions> optionsAccessor
                                    ): base(userManager, roleManager, optionsAccessor){  }
    public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
    {
        var principal = await base.CreateAsync(user);

        ((ClaimsIdentity)principal.Identity).AddClaims(new[] {
            new Claim("staff_id",user.staff_id.ToString())
        });

        return principal;
    }
}

4 - Modified Startup.cs ConfigureServices method, adding code to use my local AppClaimsPrincipalFactory class to customize the User upon login

//add Entity Framework 
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyConnectionString")));

//add Identity framework, specify which DbContext to use
services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<MyDbContext>()
                .AddDefaultTokenProviders();

//add local AppClaimsPrincipalFactory class to customize user
services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, AppClaimsPrincipalFactory>();

5 - Finally I access the claim as follows, there may be a better way but this is how I access the staff_id of the authenticated user.

int iStaffId;
if(!Int32.TryParse(User.FindFirst("staff_id").Value, out iStaffId))
{
 //throw an error because the staff_id claim should be present in iStaffId
}

Some other resources I found useful are below. Good luck.

How to extend ASP.NET Core Identity user

ASP.NET Core Identity 3.0 : Modifying the Identity Database

Configure the ASP.NET Core Identity primary key data type

Upvotes: 3

Related Questions