Search code examples
c#asp.net-coreasp.net-identityidentityserver4

AspNetCore Identity User missing ApplicationUser custom properties


I spun up a simple AspNetCore (3.0 preview) web application based on a built in template with in-app authentication (following basic tutorials).

I can run my app and when I try to go to a secured page I'm required to log in.

I register and can log in as expected. I can find my user in the AspNetUsers table in the database.

I successfully modified ApplicationUser to add CustomTag (string) and ran the EF migration and updates to get this column added to the AspNetUsers table. I populated the column using a SQL UPDATE AspNetUsers... command, so the column now contains "Hello World!".

Now I run my app but I have no useful data about the authenticated user, other than that he is authenticated.

I put a breakpoint in the controller action to view the authenticated ApplicationUser and I see the identity with 13 claims added by IdentityServer4, but I don't know how this relates to my user? The user is authenticated but name is NULL. This user doesn't have my custom property "CustomTag". Am I looking in the wrong place?

Lots of searches lead to in depth articles about how to extend the model (done that) and how to run EF migrations (done that).

Lots of searches lead to in depth articles about how to override IdentityServer4's code and UI, but there's none of that in my templated app, so I'm at a loss as to where I should be looking to modify code.

Can anyone point me to something telling me how to get my ApplicationUser custom properties visible in a controller action handler?


Solution

  • You're dealing with two separate things here. Identity is a user management system. It's separate from the authentication/authorization middleware in ASP.NET Core (which can be used with or without Identity).

    When you authenticate, a ClaimsPrincipal is created. The Entity Framework Identity provider fills some of the claims based on what's in the AspNetUsers table in the database, but only the things it intrinsically knows about. It obviously has no built-in knowledge of custom properties you've added, so those aren't included. Identity Server simply acts as a centralized identity provider, creating this principal, and then sending that back to the requesting application.

    Long and short, you're not dealing with ApplicationUser here, but rather just a collection of claims associated with a particular principal created from the authentication.

    If you want, you can fetch the actual associated ApplicationUser to get at any custom data on that any time:

    var user = await _userManager.FindByIdAsync(User.FindFirstValue(ClaimTypes.NameIdentitifer));
    

    You can also choose to supplement the claims collection via deriving from UserClaimsPrincipalFactory<TUser> and overriding CreateAsync, to add additional claims from any source, including the database. That works only directly in ASP.NET Core, though. For Identity Server, you need to implement a custom IProfileService.