Reputation: 2552
I'm a bit confused on what is the best way to customize the user profile in order to implement custom logic in the application.
Suppose you have to profile the user with this kind of attributes:
Where do I have to implement this kind of attributes? Do I have to customize IdentityUser (using ApplicationUser) or do I have to create custom claims?
Upvotes: 4
Views: 2459
Reputation: 3908
(Accidentally ran into this, and maybe this related answer is also useful for someone.)
As Gaelsa already mentioned, it's a matter of preference.
I would say, that my main consideration would be:
AspNetUsers
) and propagated to claims (when necessary) when creating the principal.AspNetUsersClaims
) right away.Example:
CanSendEmail
is a property entered and changed by the user in this identity-interface, I would store it in a strongly typed database column in AspNetUsers
.CanSendEmail
is a property maintained in another application and updated from there, I would store it as a record in the claims-table, thus in AspNetUsersClaims
.FWIW: Saving additional user-properties, does not add them as a claim automatically. You could propagate them on save by deriving from UserClaimsPrincipalFactory<TUser>
, and override CreateAsync
(see this answer).
Or maybe you could add, it when claims are requested and generated (I think, no example at hand).
Upvotes: 0
Reputation: 600
Both approach are viable, and one could argue it's a matter of preference.
I would say using only added proprerties in the IdentityUser implementation is easier to access and also require less code.
Performance wise, I would argue that the more users and data needed to be added, the better the Proprerties and so DB storage make sense, using cookies can be faster, but depanding on use and server configuration for a large amount of data especially if you want to store a lot of information for each users can proove better in the long run.
You also have to take into account data persistance if one the following is true, you will have to use Proprerties.
After that, it's really a matter of taste and specific need in your application.
Considering your example you can use IdentityUser proprerties only:
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity>GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
//There you can use display name or any attributes like a regular Model.
public LevelEnum Level { get; set; }
[Display(Name = "Is allowed to process")]
public bool CanProcess { get; set; }
public bool CanWorkOffline { get; set; }
public bool CanSendEmail { get; set; }
public bool CanViewFullName { get; set; }
}
then you can access the proprerties in your controler really easily:
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
viewModel.Level = user.Level;
same way to set
user.Level = viewModel.Level;
and saving the user using UserManager:
await _userManager.UpdateAsync(user);
//or to create
await UserManager.CreateAsync(user, model.Password);
As for the claim approach:
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
userIdentity.AddClaim(new Claim("Level", LevelEnum.Default));
return userIdentity;
}
then to access:
//claim can be null.
var claim = ((ClaimsIdentity)identity).FirstOrDefault("Level") ?? LevelEnum.Default;
And also of course, you can db stored properties to the claims if needed. Using the example for Propreties above:
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
userIdentity.AddClaim(new Claim(nameof(Level), Level));
return userIdentity;
}
Upvotes: 5