'With ASP.NET Identity is it possible to add and delete claims dynamically during an existing session?
I'm trying to add and delete claims (roles in this case) dynamically after a successful login using Identity 2 in Asp.Net 4.5.2. My application has an authentication database which contains the AspNetUsers, AspNetRoles and AspNetUserRoles tables etc and a number of other databases. During the course of a user session my users can switch between the other databases and their current claims (roles) are modified based on which database they are currently using. I'd like, therefore, to add and delete claims throughout the session. This allows me to modify which views the user has access to based on their current authorizations.
I've done many days of research on this in stack overflow and the MS Identity help pages, such as they are, and can find nothing similar to what I'm attempting to do. Based on what I've learned I've been able to add my own new claims but only during the login process, changing them at any other point works for that request but the changes do not persist and are lost by the time the next request comes in.
As far as I can tell when the claims are added during login they are encoded within the session cookie and when I add them at any other point the cookie is not modified. From my current understanding this is happening in the Identity module of the OWIN pipeline. The method where I've successfully added claims is the GenerateUserIdentityAsync method in ApplicationUser (derived from IdentityUser.
public class ApplicationUser : IdentityUser
{
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("Customer_ID", Convert.ToString(this.Customer_ID)));
userIdentity.AddClaim(new Claim("LastName", this.LastName));
userIdentity.AddClaim(new Claim("FirstName", this.FirstName));
userIdentity.AddClaim(new Claim(ClaimTypes.Role, "TestRole", null, null, "TestIssuer"));
return userIdentity;
}
Unfortunately, this doesn't help my case because I'm attempting to add/delete the claims outside the OWIN pipeline.
Is what I'm trying to do possible at all or am I going about this entirely the wrong way? I would have thought dynamic modification of authorizations is not that unusual.
Some of the many stack overflow questions I've looked at include: How to add claims in ASP.NET Identity, Dynamic User Claims in ASP.NET Identity EF and ASP.NET Identity and Claims. None of them quite cover what I'm attempting to do.
Solution 1:[1]
In Asp.net :
Adding claims to existing identity seems like a small task to accomplish. But, well, it doesn’t go so easy. We can build a middleware class and try something like shown here.
foreach(var role in user.Roles)
{
var claim = new Claim(newIdentity.RoleClaimType, role.Name);
identity.AddClaim(claim);
}
And in Asp.net core:
There’s the correct way to edit existing identity and it’s called claims transformation. Basically, we have to write a custom class that implements the IClaimsTransformation interface. Documentation doesn’t give much information about it but the most important thing is said – we need to clone the given identity.
In short, here’s how the process goes:
Clone current user identity
Add custom claims
Return cloned identity
public class AddRolesClaimsTransformation : IClaimsTransformation { private readonly IUserService _userService; public class AddRolesClaimsTransformation : IClaimsTransformation { private readonly IUserService _userService; public AddRolesClaimsTransformation(IUserService userService) { _userService = userService; } public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { // Clone current identity var clone = principal.Clone(); var newIdentity = (ClaimsIdentity)clone.Identity; // Support AD and local accounts var nameId = principal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier || c.Type == ClaimTypes.Name); if (nameId == null) { return principal; } // Get user from database var user = await _userService.GetByUserName(nameId.Value); if (user == null) { return principal; } // Add role claims to cloned identity foreach (var role in user.Roles) { var claim = new Claim(newIdentity.RoleClaimType, role.Name); newIdentity.AddClaim(claim); } return clone; } }
The final thing to do is to register claims transformation with dependency injection in the ConfigureServices() method of the Startup class.
services.AddScoped<IClaimsTransformation, AddRolesClaimsTransformation>();
enter code here
Based on https://gunnarpeipman.com/aspnet-core-adding-claims-to-existing-identity/
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |