Checking for one of multiple policies with Authorize attribute in ASP.NET Core Identity

Blake Rivell picture Blake Rivell · Nov 9, 2017 · Viewed 7.2k times · Source

I have setup a standard authentication system up in an ASP.NET Core application.

Users, Roles, RoleClaims(acting as permissions)

In Startup.cs I create a policy for each Role and each Permission. Assuming this would give me full flexibility in my Views to be able to say I want this button to show if user is part of a role that has claim DeleteCustomer or if User belongs to role Superuser.

How can I do an OR condition using the Authorize attribute. For example all throughout my site I want SuperuserRole Policy to have full permission to everything.

Over an action method let's say I have the following:

[Authorize(Policy = "EditCustomer")]

This will require that the logged in user is assigned to a role that has the claim: Edit.Customer since I am creating a policy for the claim Edit.Customer. This is all working fine, but how do I say I would like any User with the Role Superuser to be able to access EditCustomer action method. Superuser is in the database as a Role and additionally added as a policy called RequireSuperUser.

Answer

Richard Mneyan picture Richard Mneyan · Feb 9, 2018

You can add OR condition in Startup.cs:

services.AddAuthorization(options => {
    options.AddPolicy("EditCustomer", policy =>
        policy.RequireAssertion(context => 
        context.User.HasClaim(c => (c.Type == "DeleteCustomer" || c.Type == "Superuser"))));
});

I was facing similar issue where I wanted only "John Doe", "Jane Doe" users to view "Ending Contracts" screen OR anyone only from "MIS" department also to be able to access the same screen. The below worked for me, where I have claim types "department" and "UserName":

services.AddAuthorization(options => {
    options.AddPolicy("EndingContracts", policy =>
        policy.RequireAssertion(context => context.User.HasClaim(c => (c.Type == "department" && c.Value == "MIS" ||
        c.Type == "UserName" && "John Doe, Jane Doe".Contains(c.Value)))));
});