I've an ASP.NET Core (based on .NET Framework) using Windows Authentication. Point is, I need to add a role claim on that user and this role is stored in a distant database.
I've read so much thing about OWIN/Cookie/UserManager/UserStore/Identity and so on that I'm lost.
Question : How do I add a role claim for current user logged in (windows) for the whole application in the easiest way?
What I need is to easily use [Authorize(Role= "MyAddedRole")]
or bool res = User.IsInRole("MyAddedRole")
Thanks
Adding claims checks Claim based authorization checks are declarative - the developer embeds them within their code, against a controller or an action within a controller, specifying claims which the current user must possess, and optionally the value the claim must hold to access the requested resource.
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.
The RoleClaimType property specifies the claim type of the claim that should be used to provide the value for the role when evaluating this ClaimsIdentity object. The property is set by the constructor. A common value is ClaimTypes.
Claims are a method of providing information about a user, and roles are a description of a user by way of which roles they belong.
Answering myself, so what I did :
Create my own UserClaimStore (I only need this store, not the others):
public class MyIdentityStore :
IUserClaimStore<IdentityUser>
{
private MyDbContext _myDbContext;
private bool _disposed = false;
public MyIdentityStore(MyDbContext myDbContext)
{
_myDbContext = myDbContext;
}
#region IUserClaimStore
public Task<IList<Claim>> GetClaimsAsync(IdentityUser user, CancellationToken cancellationToken)
{
// logic here to retrieve claims from my own database using _myDbContext
}
// All other methods from interface throwing System.NotSupportedException.
#endregion
#region IDisposable Support
protected virtual void Dispose(bool disposing)
{ /* do cleanup */ }
#endregion
}
Then created my own ClaimTransformer :
public class MyClaimsTransformer : IClaimsTransformer
{
private UserManager<IdentityUser> _userManager;
public MyClaimsTransformer(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
{
var identity = ((ClaimsIdentity)context.Principal.Identity);
// Accessing the UserClaimStore described above
var claims = await _userManager.GetClaimsAsync(new IdentityUser(identity.Name));
identity.AddClaims(claims);
return await Task.FromResult(context.Principal);
}
}
Endly, in Startup.cs :
public void ConfigureServices(IServiceCollection services)
{
/* All other stuff here */
// Adding Database connection
services.AddDbContext<MyDbContext>(o => /* my options */);
// Associates our database and store to identity
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<MyDbContext>()
.AddUserStore<MyIdentityStore>();
// Claims transformation from database to claims
services.AddTransient<IClaimsTransformer, MyClaimsTransformer>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
/* All other stuff here */
app.UseIdentity();
app.UseClaimsTransformation(async (context) =>
{ // Retrieve user claims from database
IClaimsTransformer transformer = context.Context.RequestServices.GetRequiredService<IClaimsTransformer>();
return await transformer.TransformAsync(context);
});
}
And now I can freely use [Authorize(Roles = "MyRole")]
or User.IsInRole("MyRole")
or even User.HasClaim(/* */)
!
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