I've always used role authorization in my .net application. However, I'm building a demo app and want to give claims a try. I've always decorated my controller like this where either an admin or User with full access can be authorized.
[[Authorize(Roles = "IsApiUserFullAccess", "IsAdmin") ]]
However, I can't accomplish the same with claims. In my startup, I have these two claims policies. How can I decorate my controller or change these policies to make either claims to be authorize by my controller?
options.AddPolicy("IsApiUserFullAccess", policy => policy.RequireClaim("apiuser.fullaccess", "true"));
options.AddPolicy("IsAdmin", policy => policy.RequireClaim("administrator", "true"));
In Role-based authorization, applications enforce access by roles. These roles can be used in authorized attributes in your code. Alternatively, claims-based authorization enforces permissions by using information about the user rather than relying on a single role declaration.
Role-based authorization enables customer management of users and their roles independently from Payment Feature Services. Role-based authorization has a user registry that is not part of Payment Feature Services. This authorization is optional and does not replace the current model.
Policy-based authentication is a new approach that provides a richer and more expressive model. This is because a policy is a collection of requirements based on claims and custom logic based on any other information that can be injected from the HTTP context or external sources.
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.
You can use the RequireAssertion() method which accepts a Func<> to fullfill a policy.
Source
Example:
services.AddAuthorization(options =>
{
options.AddPolicy("AdminOrFullAccess", policy =>
policy.RequireAssertion(context =>
{
bool isApiUserFullAccess = context.User.HasClaim(c => ...);
bool isAdmin = context.User.IsInRole("ADMIN_ROLE");
return isAdmin || isApiUserFullAccess;
});
});
One way would be to build a custom policy with a requirement and handler that ORs the user's claims, like so:
// Marker class
public class HasFullAccessOrAdminRequirement : IAuthorizationRequirement {}
public class HasFullAccessOrAdminHandler
: AuthorizationHandler<HasFullAccessOrAdminRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
HasFullAccessOrAdminRequirement requirement)
{
var user = context.User;
if (user.HasClaim(...) || user.HasClaim(...))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
Then register it:
options.AddPolicy("AdminOrFullAccess", builder =>
builder.AddRequirements(new HasFullAccessOrAdminRequirement());
Then use it: [Authorize("AdminOrFullAccess")]
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