In this article I will explain how to simply create an AuthorizeAttribute that accepts parameters of type enum in order to avoid roles hard coding.

Have you ever tried to use an [Authorize] attribute and assign roles for example with an Enum value in one of your ASP.NET MVC projects?

If so, you will get the following error message when compiling:

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

 

It is because you need to use static values and it makes impossible to use an Enum to set properties of an Attribute. It means that you can not set the property Roles of an [AuthorizeAttribute] with an Enum value.

That is frustrating, because I personally don't like having to hard code roles in an application. It makes the application dirty and more complicated to maintain.

 

Hopefully, ASP.NET MVC allows us to customize the [AuthorizeAttribute] easily without having to override the standard security process.

 

Creation

For our needs we will create the following Enum to declare roles:

namespace MvcApplication.HowTo.Enums
{
    public enum Role
    {
        Administrator = 1,
        UserWithPrivileges = 2,
        User = 3,
    }
}

 

Now we are going to create a custom [AuthorizeAttribute] that accepts Enum as parameters in the constructor. It will inherit from the standard System.Web.Mvc.AuthorizeAttribute:

using System;
using System.Linq;
using System.Web.Mvc;

namespace MvcApplication.HowTo.Attributes
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class AuthorizeEnumAttribute : AuthorizeAttribute
    {
        public AuthorizeEnumAttribute(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)));
        }
    }
}

As you can see we have to pay attention to several things here:

 

Example of use

Let's say we want to authorize only users with roles Administrator or UserWithPrivileges on the HomeController action named ThePrivilegeZone. ThePrivilegeZone action will be decorated with our custom authorize attribute like bellow:

using System.Web.Mvc;
using MvcApplication.HowTo.Attributes;
using MvcApplication.HowTo.Enums;

namespace MvcApplication.HowTo.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            return View();
        }

        public ActionResult About()
        {
            return View();
        }

        [AuthorizeEnum(Role.Administrator, Role.UserWithPrivileges)]
        public ActionResult ThePrivilegeZone()
        {
            return View();
        }
    }
}

Our code is clean like that, isn't it?

 

To go further

If you take a look with a tool like Reflector, it is interesting to understand how the action ThePrivilegeZone is decorated when compiled. Here is a screenshot:

ThePrivilegeZone action with Reflector

We understand that once compiled, Role Enum values are used and not names. Here 1 (Administrator) and 2 (UserWithPrivileges).

Note that if you use an Enum for your roles without setting values like we did here, Enum values will be 0, 1, 2, etc. to the number of your roles less 1.

 

 

Summary

We have seen how to create and use a custom AuthorizeAttribute that accepts parameters of type enum. Here we are only setting roles, but depending on your needs, you can do the same with users. I personally use this custom attribute in my framework so that I am able to reuse it in all my ASP.NET MVC projects.

You can download the example solution here:

Download the Authorize Enum Solution

(Note that the project uses ASP.NET MVC 3)

 

Please feel free to comment or contact me if you have any question about this article.


Comments

Add a comment

(Will not be published)

Back to articles