Showing posts with label authorize. Show all posts
Showing posts with label authorize. Show all posts

Friday, November 6, 2015

ASP.NET MVC >> Using enumerations in AuthorizeAttribute to allow the actions to be invoked by multiple roles

Consider a scenario where you need all/ some of the actions of a controller to be invoked by users having specific roles. For example, a "AdminController" which can be accessed only be users having "Admin" or "SuperUser" roles.

Now, its easy to pass multiple roles as a string in Authorize attribute as below:
[Authorize(Roles="Roles,SuperUser")]

However, this is an absolute maintenance nightmare, because if any of the roles are renamed you will need to remember to update at multiple places.

Imagine creating enum as below

    public enum Roles
    {
        User,
        Admin,
        SuperUser
    }

But as the Roles parameter in Authorize attribute is of string type, it wont allow you to pass multiple enum values there.

In order to fix this issue, we need to to create a new attribute inheriting from MVC's AuthorizeAttribute:

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class AuthorizeEnum: AuthorizeAttribute
    {
        public AuthorizeEnum(params object[] roles)
        {
            if (roles.Any(r => r.GetType().BaseType != typeof(Enum)))
                throw new ArgumentException("roles");

            this.Roles = string.Join(",", roles.Select(r => Enum.GetName(r.GetType(), r)));
        }
    }

Now, this attribute can be used to decorate the controllers and/ or actions to pass multiple roles as enum values instead of strings.

[AuthorizeEnum(Roles.User, Roles.Admin)]
public partial class AdminController 
{
..........
}