Authorize Attribute with Multiple Roles

role based authorization in mvc 5
custom role based authorization in asp.net core
role based authorization in web api
authorize attribute net core
custom role based authorization in asp.net mvc
authorize(roles not working)
asp.net core permission based authorization
asp.net core 2.2 identity roles

I would like to add Authorization to a controller, for multiple Roles at once.

Normally that would look like this:

[Authorize(Roles = "RoleA,RoleB,RoleC")]
public async Task<ActionResult> Index()
{
}

But I have stored my Roles in consts, since they might change or be extended at some point.

public const RoleA = "RoleA";
public const RoleB = "RoleB";
public const RoleC = "RoleC";

I cannot do this, since the string must be known at compile time:

[Authorize(Roles = string.join(",",RoleA,RoleB,RoleC)]
public async Task<ActionResult> Index()
{
}

Is there a way to circumvent the problem?

I COULD write a const which simply contains "RoleA,RoleB,RoleC" - but I dislike magic strings and this is a magic string. Changing the name of a Role and forgetting to change the combined string would be a disaster.

I am using MVC5. ASP.NET Identity and the Role are known at compile time.

Try to create custom authorize attribute like this.

public class AuthorizeRolesAttribute : AuthorizeAttribute
{
    public AuthorizeRolesAttribute(params string[] roles) : base()
    {
        Roles = string.Join(",", roles);
    }
}

Assuming your roles will be the same for multiple controllers, create a helper class:

public static class Role
{
    public const string Administrator = "Administrator";
    public const string Assistant = "Assistant";
}

Then use it like so:

public class MyController : Controller
{
    [AuthorizeRoles(Role.Administrator, Role.Assistant)]
    public ActionResult AdminOrAssistant()
    {                       
        return View();
    }
}

Authorize Attribute with Multiple Roles, Try to create custom authorize attribute like this. public class AuthorizeRolesAttribute : AuthorizeAttribute { public  You can specify multiple roles as a comma separated list: [Authorize(Roles = "HRManager,Finance")] public class SalaryController : Controller { } This controller would be only accessible by users who are members of the HRManager role or the Finance role.

Make sure you are deriving your custom attribute class off System.Web.Mvc.AuthorizeAttribute and NOT System.Web.Http.AuthorizeAttribute.

I ran into the same problem. Once I changed it, everything worked.

You may also want to add the following to your custom attribute class:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] 

Role-based authorization in ASP.NET Core, If you apply multiple attributes then an accessing user must be a member of all the roles specified; the following sample requires that a user must be a member of both the PowerUser and ControlPanelUser role. In This part we will learn how to configure and store roll in separate class and use these roll dynamically . link of work in this tutorials https://github.c

The best and simplest way I found to resolve this problem is just to concatenate roles in the Authorize attribute.

[Authorize(Roles = CustomRoles.Admin + "," + CustomRoles.OtherRole)]

with CustomRole a class with constant strings like this :

public static class CustomRoles
{
    public const string Admin = "Admin";
    // and so on..
}

Role based Authorization, If you apply multiple attributes then an accessing user must be a member of all the roles specified; the following sample requires that a user must be a member of both the PowerUser and ControlPanelUser role. If you find yourself applying those 2 roles often you can wrap them in their own Authorize. This is really an extension of the accepted answer. using System.Web.Mvc; public class AuthorizeAdminOrMember : AuthorizeAttribute { public AuthorizeAdminOrMember() { Roles = "members, admin"; } }

What i did is the answer in @Tieson

I tweak a little in his answer. Instead of string.Join why not convert it to list?

Here is my answer:

public class AuthorizeRolesAttribute : AuthorizeAttribute
{
    private new List<string> Roles;
    public AuthorizeRolesAttribute(params string[] roles) : base()
    {
        Roles = roles.toList()
    }
}

And then check the if the role is valid overriding OnAuthorization

public override void OnAuthorization(HttpActionContext actionContext)
{
            if (Roles == null)
                HandleUnauthorizedRequest(actionContext);
            else
            {
                ClaimsIdentity claimsIdentity = HttpContext.Current.User.Identity as ClaimsIdentity;
                string _role = claimsIdentity.FindFirst(ClaimTypes.Role).Value;
                bool isAuthorize = Roles.Any(role => role == _role);

                if(!isAuthorize)
                    HandleUnauthorizedRequest(actionContext);
            }
        }

And there you have it, it is now validating if the role is authorized to access the resource

Authorize Attribute with Multiple Roles, In This part we will learn how to configure and store roll in separate class and use these roll Duration: 9:46 Posted: Dec 6, 2018 Step 1: Run the application and create following roles Manager Sales Executive Sales Manager Step 2: Create the following users using Register View manager@mssales.com with role as Manager salesmanager@mssales.com Step 3: Open the ProductController class. This class contains Create and

I feel like a custom authorize attribute is overkill for this issue unless you have a large amount of roles.

Since the string must be known at compile time, why not make a static Role class that contains public strings of the roles you have defined, and then add comma separated strings with certain roles that you want to authorize:

public static class Roles
{
    public const string ADMIN = "Admin";
    public const string VIEWER = "Viewer";

    public const string ADMIN_OR_VIEWER = ADMIN + "," + VIEWER;
}

And then you can use the Authorize Attribute like so on the Controller Class or the Controller Method (or both):

[Authorize(Roles = Roles.ADMIN]
public class ExampleController : Controller
{
    [Authorize(Roles = Roles.ADMIN_OR_VIEWER)
    public ActionResult Create()
    {
        ..code here...
    }
}

Policy-based Authorization in ASP.NET Core - A Deep Dive, The Authorize attribute enables you to restrict access to resources based on You can also specify multiple roles, separated by a comma. Gets a value that indicates whether multiple filters are allowed.(Inherited from FilterAttribute.) Roles: Gets or sets the authorized roles. TypeId: Gets a unique identifier for this attribute.(Overrides Attribute.TypeId.) Users: Gets or sets the authorized users.

ASP.NET MVC 3: Strongly typed Authorize Attribute with multiple , In detail, the controller or the action is marked with the Authorize attribute that defines which roles or users are granted access to the content  With the enum I can only authorize ONE role. I can't figure out how to authorize two. I have tried something like [Authorize(Roles=MyEnum.Admin, MyEnum.Moderator)] but that wont compile. Someone once suggested this: [Authorize(Roles=MyEnum.Admin)] [Authorize(MyEnum.Moderator)] public ActionResult myAction() { } but it doesn't work as an OR.

Access same Action Method by Multiple Roles in ASP.NET MVC , The Article also creates a custom AuthorizeAttribute class for providing Authorization based on user roles. The Absolutely Awesome Book on C#  If you have lots of roles you can end up with long Authorize attributes, e.g. [Authorize(Roles = “Staff,HrManager,BizManager,DevManage,Admin,SuperAdmin”)]. Because Authorize is an attribute then the string has to be a constant, e.g. you can’t have $”{RoleConstants.StaffRole}”.

Role Base Authorization In ASP.NET Core 2.1, However, authorization requires an authentication mechanism. We can also apply multiple Authorize attributes and specify the role that has  Underneath the covers, role-based authorization and claims-based authorization use a requirement, a requirement handler, and a pre-configured policy. These building blocks support the expression of authorization evaluations in code.

Comments
  • are you using public const string RoleA = "RoleA"; or as you have written in question?
  • possible duplicate of allow multiple roles to access controller action
  • Now that's an idea worthy of Mac Gyver ;)
  • Very nice solution :)
  • I also like this solution a lot, especially because I can let my Role be an enum rather than a string. What would a good namespace and location in the project hierarchy be for placing this custom authorize attribute?
  • I am not sure what is going on here, but this did NOT help me, any user regardless of the role was able to access the method.
  • Same issue as @Urielzen, but it was fixed by the answer below from Jerry Finegan (using "System.Web.Mvc.AuthorizeAttribute and NOT System.Web.Http.AuthorizeAttribute")
  • I just tried this and found referencing the library System.Web.Http.AuthorizeAttribute INSTEAD OF System.Web.Mvc.AuthorizeAttribute
  • Valueable; but this should be a comment; not an answer.
  • Simple and elegant solution!
  • Both your answer and the accepted answer will trigger authorization if implemented correctly (I'm using the accepted in a production web app). Proposing an edit to remove the comments about the accepted answer.
  • This example doesn't work, or at least not the way you might think. For example, while novel the ADMIN_OR_VIEWER role on the action is redundant because you will not be allowed to get to the Create method if you don't already have the ADMIN role. In this case VIEWER will never be able to invoke Create method.
  • This solution is not scalable too. There will be a point where you have too many roles with different actions and you shouldnt create every combination