This is my first attempt to use the ASP.NET identity with the builtin authentication. All previous attempts resulted in having a manual check for user credentials and then setting FormsAuthentication
AuthCookie
. But I had some problems with a signalR connection not having authentication information this way. So I started from scratch with the builtin authentication.
So I extended my ApplicationUser
object with some fields:
public class ApplicationUser : IdentityUser
{
public long SteamId { get; set; }
public string Avatar { get; internal set; }
public string Name { get; internal set; }
public int Credits { get; internal set; }
public long? DiscordId { get; internal set; }
public DateTime? LastLogin { get; internal set; }
public DateTime RegisterDate { get; internal set; }
}
These fields will create new columns in my AspNetUsers
table. The problem is, I can't access these values in my views. For that I need to use claims if I understand correctly. These claims are stored in another table called AspNetUserClaims
. So I have to add those claims to the user
await UserManager.AddClaimAsync(user.Id, new Claim("Avatar", user.Avatar));
and creating a extension method to get the avatar from the principal
public static class ClaimsPrincipalExtension
{
public static string GetAvatar(this ClaimsPrincipal principal)
{
var avatar = principal.Claims.FirstOrDefault(c => c.Type == "Avatar");
return avatar?.Value;
}
}
Now I can access the avatar in my view
@(((ClaimsPrincipal)User).GetAvatar())
I don't think that's a really good and clean way to do this, but this is the first time I am using it, so I don't know what's the best practices to do. There are three main reasons why I don't like it:
- The avatar is stored twice, once in the
AspNetUsers
table as column and once as a new entry inAspNetUserClaims
- Fields like
SteamId
,Credits
orRegisterDate
are saved as string in theAspNetUserClaims
table, and I have to convert them toint
,long
orDateTime
in the extension method - I have to write an extension method for every property I'll add to the
ApplicationUser
What is the best way to handle additional fields?
- Might it be an option to create a new object called
AdditionalUserInformation
and store the json serialized string as claim and just have one extension method to return the object? Then the properties would have the correct type. - Or is there a way to access the properties of the
ApplicationUser
in the view? - Or is the problem the use of those in the view? Should I access them in the controller and create a Model for the view containing all information? What about a _Layout page or a _navigation partial view then? They also might need the information of the user. I think I can't feed them with the controllers.
I also checked some examples. Mostly they add those extension methods and mostly just string properties.
Examples
- How to extend available properties of User.Identity
- How should I access my ApplicationUser properties from within my MVC 6 Views?
I am currently kinda stuck here on finding the best and maybe clean solution.