Reputation: 1499
There is a user class, which has field named "Avatar", which stores path to his profile picture. I want to show it in header inside the partial view. So I desided to add a claim to user identity. I put this lines of code inside my IdentityConfig.cs
class:
public override Task<ClaimsIdentity> CreateUserIdentityAsync(AppUser user)
{
if(!System.String.IsNullOrEmpty(user.Avatar))
user.Claims.Add(new AppUserClaim() { ClaimType = "avatar", ClaimValue = user.Avatar});
return user.GenerateUserIdentityAsync((AppUserManager)UserManager);
}
But there is a problem: after a period of time (aprox. 1 hour) this Claim disappears and there's no avatar shown. I found out, that asp.net identity framework regenerates user's identity every 30 minutes (default). And according to this:
regenerateIdentityCallback: (manager, user) =>
user.GenerateUserIdentityAsync(manager)
it calls GenerateUserIdentityAsync
method of user's class. At this momment it becomes not clear to me. There are two, on the first sight, similar methods of generating user identity:
usermanager
class as a parameter - public async Task<ClaimsIdentity> GenerateUserIdentityAsync(AppUserManager manager)
public override Task<ClaimsIdentity> CreateUserIdentityAsync(AppUser user)
What's the purpose of that? Where each of this methods has been used? And which one should I use to add custom user claim?
Upvotes: 2
Views: 3951
Reputation: 696
There is another way. For .NET 6.
using Microsoft.AspNetCore.Authentication;
using System.Security.Claims;
public class MyClaimsTransformation : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity();
var claimType = "myNewClaim";
if (!principal.HasClaim(claim => claim.Type == claimType))
{
claimsIdentity.AddClaim(new Claim(claimType, "myClaimValue"));
}
principal.AddIdentity(claimsIdentity);
return Task.FromResult(principal);
}
}
The IClaimsTransformation interface and the MyClaimsTransformation class can be registered as a service:
builder.Services.AddTransient<IClaimsTransformation, MyClaimsTransformation>();
Source: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/claims?view=aspnetcore-6.0
Upvotes: 0
Reputation: 1634
I've refactored a standard ASP.NET MVC project a little so I don't repeat the code for adding claims.
Startup.Auth.cs:
public void ConfigureAuth(IAppBuilder app, Container container)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, User>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => IdentityHelper.GenerateUserIdentityAsync(user, manager))
}
});
}
Then I made a static helper method to generate the identity:
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(User user, UserManager<User> manager)
{
var userIdentity = await manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie).ConfigureAwait(false);
userIdentity.AddClaim(new Claim("Key", "Value"));
return userIdentity;
}
Now you will be able to reuse this helper from your SignInManager.
public class ApplicationSignInManager : SignInManager<User, string>
{
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
public override Task<ClaimsIdentity> CreateUserIdentityAsync(User user)
{
return IdentityHelper.GenerateUserIdentityHelperAsync(user, (ApplicationUserManager)UserManager);
}
}
Upvotes: 4