How to Add Claims in ASP.NET Identity

How to add claims in ASP.NET Identity

Perhaps the following article can help:

var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, "Brock"));
claims.Add(new Claim(ClaimTypes.Email, "brockallen@gmail.com"));
var id = new ClaimsIdentity(claims,DefaultAuthenticationTypes.ApplicationCookie);

var ctx = Request.GetOwinContext();
var authenticationManager = ctx.Authentication;
authenticationManager.SignIn(id);

How to add claims based on the fields from users table in ASP.NET Core MVC?

According to your description, I suggest you could create a custom claim factory which inherits UserClaimsPrincipalFactory.

Then you could add the additional claims in the override GenerateClaimsAsync method.

More details, you could refer to below codes:

MyUserClaimsPrincipalFactory:

using IdentityTestDemo.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace IdentityTestDemo
{
public class MyUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<IdentityUser>
{
private ApplicationDbContext _appliationDbContext;
public MyUserClaimsPrincipalFactory(
UserManager<IdentityUser> userManager,
IOptions<IdentityOptions> optionsAccessor,ApplicationDbContext applicationDbContext)
: base(userManager, optionsAccessor)
{
_appliationDbContext = applicationDbContext;
}

protected override async Task<ClaimsIdentity> GenerateClaimsAsync(IdentityUser user)
{
//get the data from dbcontext
var Iuser= _appliationDbContext.Users.Where(x => x.EmailConfirmed == true).FirstOrDefault();

var identity = await base.GenerateClaimsAsync(user);
//Get the data from EF core

identity.AddClaim(new Claim("EmailTest", Iuser.Email));
return identity;
}
}
}

Startup.cs:

    public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>().AddClaimsPrincipalFactory<MyUserClaimsPrincipalFactory>(); ;
services.AddControllersWithViews();
services.AddRazorPages();
}

In the controller to get the claims:

        var result = User.FindFirst("EmailTest").Value;

Result:

Sample Image

Add claims on successful login and retrieve it elsewhere in the application

You must add your claims before login not after. Consider this example:

public async Task<ActionResult> Login(LoginViewModel model,string returnUrl)
{
var user = UserManager.Find(model.Email, model.Password);
if(user!=null)
{
var ident = UserManager.CreateIdentity(user,
DefaultAuthenticationTypes.ApplicationCookie);
ident.AddClaims(new[] {
new Claim("MyClaimName","MyClaimValue"),
new Claim("YetAnotherClaim","YetAnotherValue"),
});
AuthenticationManager.SignIn(
new AuthenticationProperties() { IsPersistent = true },
ident);
return RedirectToLocal(returnUrl);
}
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}

Now since we have injected our claims while signing in, we have access to claims wherever we want:

((ClaimsIdentity)User.Identity).FindFirst("MyClaimName");

Also you could add your claims in ApplicationUser.GenerateUserIdentityAsync() method. By adding your claims in this method you could use SignInManager.PasswordSignInAsync() method to sign in users without any modification to default Login action method.

public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
userIdentity .AddClaims(new[] {
new Claim("MyClaimName","MyClaimValue"),
new Claim("YetAnotherClaim","YetAnotherValue"),
});
return userIdentity;
}
}

Add persistent claim with Asp.Net Core Identity

I am not sure when project need to add the external claims. Identity is based on cookie, every request will carry the cookie, so the identity can parse the cookie as the claims. If you want to reload ClaimsIdentity, you need to reuse the method SignInAsync to regenerate cookie. But there is a global method IClaimsTransformation can help you add the temporary claim according to different situation.

public class Tanstromer : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var claims = new List<Claim> { };
var identity = principal.Identity as ClaimsIdentity;
identity.AddClaim(new Claim("",""));

//you can add some justification here
var userPrinicpal = new ClaimsPrincipal(identity);
return Task.FromResult(principal);
}
}

Add it in ConfigureService

services.AddScoped<IClaimsTransformation, Tanstromer>();

ASP.NET Core custom claims are lost

I finally figured out the culprit myself. It turns out that it did have something to do with the cookie refresh process.

My ApplicationUser class has a navigation property, which contains all the information that my custom claims transformation class uses to fill up the claims. So all is good there.

Except that I didn't override the UserStore's
Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken)) method, which is invoked when the cookie is refreshed. By default, Identity won't load this navigation property, in which case the object is null and the claims will be 'lost' in the process.

So in the end I added an override and added some eager loading, and the problem was resolved.

How to add claims to the HttpContext User on sign in

To add or transform custom claims, implement and use a custom ClaimsAuthenticationManager. How To: Transform Incoming Claims.

public class ClaimsTransformationModule : ClaimsAuthenticationManager {  
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal) {
if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated == true) {
var identity = (ClaimsIdentity)incomingPrincipal.Identity;
var user = GetUserData(identity);

identity.AddClaim(new Claim("fullname", user.GetFullName(user.UserName)));
identity.AddClaim(new Claim("avatarUrl", user.AvatarUrl));
}

return incomingPrincipal;
}
}

Here, GetUserData() retrieves the User entity from the DB, given the user name.

Register this transformer in the web.config:

<system.identityModel>
<identityConfiguration>
<claimsAuthenticationManager type="MyProject.ClaimsTransformationModule , MyProject, Version=1.0.0.0, Culture=neutral" />
</identityConfiguration>
</system.identityModel>


Related Topics



Leave a reply



Submit