Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to have a claims authorization with an OR condition like roles?

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"));
like image 993
zAnthony Avatar asked Dec 05 '19 19:12

zAnthony


People also ask

What is the difference between a role and a claim?

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.

What is role-based Authorisation?

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.

What is policy based authorization?

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.

How would you implement claims-based authentication in .NET Core?

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.


2 Answers

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;
             });                    
});
like image 140
jBelanger Avatar answered Oct 17 '22 14:10

jBelanger


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")]

like image 36
ChiefTwoPencils Avatar answered Oct 17 '22 14:10

ChiefTwoPencils