Search code examples
c#authorize-attribute

Pass an array of enums in C#


I need to allow multiple roles to have access to a method, in a controller in C# Web api.

I have a custom AuthorizeAttribute which takes an enum of role type, how can I make it so it accepts multiple enums ie. a variable length array of enums.

This is the code I have written for the Attribute:

private readonly RoleEnum roleInApplication;

public ScopeAuthorizeAttribute(RoleEnum roleInApplication)
{
    this.roleInApplication = roleInApplication;
}

public override void OnAuthorization(HttpActionContext actionContext)
{
    base.OnAuthorization(actionContext);
    .......
    var relatedPermisssionRole = (db call to get the rolename..etc)
    RoleEnum role;
    if (Enum.TryParse(relatedPermisssionRole, out role) && role == roleInApplication)
    {
            // Succeed if the scope array contains the required scope
            return;
     }
  }

    HandleUnauthorizedRequest(actionContext);
}

And in the controller, I use it like this:

[ScopeAuthorize(RoleEnum.ADMIN)]
public async Task<IHttpActionResult> Create(MyModel model)

How do I allow multiple roles? eg.

[ScopeAuthorize(RoleEnum.ADMIN, RoleEnum.USER)]
public async Task<IHttpActionResult> Create(MyModel model)

Solution

  • You could use params as in public ScopeAuthorizeAttribute(params RoleEnum[] roleInApplication) but in reality you are trying to solve the issue in the wrong way, consider using Flags instead:

    [FlagsAttribute] 
    enum Role
    {
      None = 0,
      Admin = 1,
      User = 2,
      SomeOtherRole = 4
    }
    

    Then you can pass your roles as one parameter using bitwise OR:

    [ScopeAuthorize(Role.Admin | Role.User)]
    public async Task<IHttpActionResult> Create(MyModel model)
    

    But don't just copy my code snippet, it is definitely worth having a good read of the documentation for Flags esp. Guidelines for FlagsAttribute and Enum to ensure you use this pattern correctly. There are a few caveats you must be aware of, which are not immediately obvious. It will be a 5 minutes well spent.

    Also, I suggest you refrain from suffixing your enum with the word Enum and using UPPERCASE for your enum names.