How can I create a custom authorize claim in MVC Core 2.0 (using AspNetCore.identity) to verify a custom user boolean property? I have extended the IdentityUser (ApplicationUser) to include a boolean value "IsDeveloper". I am using claims based authentication and would like to add a custom claim, but am not certain where to start. How can I create a custom claim that will:
I understand the core identity claims MSDN: Claims Based Authentication, but am new to custom claims, so I am not sure where to begin. The Online documents that I have found do not work or does not fit my scenario.
The claims-based authorization works by checking if the user has a claim to access an URL. In ASP.NET Core we create policies to implement the Claims-Based Authorization. The policy defines what claims that user must process to satisfy the policy. We apply the policy on the Controller, action method, razor page, etc.
Claims can be created from any user or identity data which can be issued using a trusted identity provider or ASP.NET Core identity. A claim is a name value pair that represents what the subject is, not what the subject can do.
So, you need to create custom claims somewhere and then check it through a custom policy or manually.
You can do something like this:
In your controller action that returns jwt-token you can add your custom claim
:
[HttpGet]
public dynamic GetToken(string login, string password)
{
var handler = new JwtSecurityTokenHandler();
var sec = "12312313212312313213213123123132123123132132132131231313212313232131231231313212313213132123131321313213213131231231213213131311";
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(sec));
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
var user = GetUserFromDb(login);
var identity = new ClaimsIdentity(new GenericIdentity(user.Email), new[] { new Claim("user_id", user.Id) });
if (user.IsDeveloper)
identity.AddClaim(new Claim("IsDeveloper", "true"));
var token = handler.CreateJwtSecurityToken(subject: identity,
signingCredentials: signingCredentials,
audience: "ExampleAudience",
issuer: "ExampleIssuer",
expires: DateTime.UtcNow.AddSeconds(100));
return handler.WriteToken(token);
}
You need to implement a custom IUserClaimsPrincipalFactory
or use UserClaimsPrincipalFactory
as a base class:
public class ApplicationClaimsIdentityFactory: Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory <ApplicationUser>
{
UserManager<ApplicationUser> _userManager;
public ApplicationClaimsIdentityFactory(UserManager<ApplicationUser> userManager,
IOptions<IdentityOptions> optionsAccessor):base(userManager, optionsAccessor)
{}
public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
{
var principal = await base.CreateAsync(user);
if (user.IsDeveloper)
{
((ClaimsIdentity)principal.Identity).AddClaims(new[] {
new Claim("IsDeveloper", "true")
});
}
return principal;
}
}
then you need to register it in Startup.ConfigureServices
:
services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, ApplicationClaimsIdentityFactory>();
In Startup.ConfigureServices
:
services.AddAuthorization(options =>
{
options.AddPolicy("Developer", policy =>
policy.RequireClaim("IsDeveloper", "true"));
});
and protect your action for developers:
[Authorize(Policy = "Developer"), HttpGet]
public string DeveloperSecret()
{
return "Hello Developer"
}
Somewhere in the controller:
bool isDeveloper = User.Claims.Any(c => c.Type == "IsDeveloper" && c.Value == "true")
If you are using some other authentication the idea should be the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With