Thursday, September 29, 2011

Customised attribute in ASP.NET MVC


When developing a multilingual website, I had to change the default route in the Global.asax.cs file (this might be the subject of another post here...).
Now the route is "{lang}/{controller}/{action}/{id}" instead of the traditional "{controller}/{action}/{id}".
On top of that, all the routes are translated according to the current culture.

This change introduced a new problem: the utilisation of the "Authorize" attribute redirects the user when he is not connected (or when he is not in role, etc.):

   1:  [Authorize(Roles = "Admin")]
   2:  public class AdministrationController : Controller
   3:  {
   4:      public ActionResult Index()
   5:      {
   6:          return View();
   7:      }
   8:      
   9:      [........]
  10:  }

By default the user is redirected on "/Account/LogOn". You can change this in the "web.config" file here:

   1:  <authentication mode="Forms">
   2:    <forms loginUrl="~/Account/LogOn" timeout="28800" />
   3:  </authentication>

For my problem, it was not a solution because this URL changes according to the culture of the user...
I can verify at each action if the user is in the "Admin" role and make the correct redirection. But this is annoying, repetitive and it is easy to forget one of the actions...

A good solution for me was creating a customised attribute for my controller: each one of my actions is protected.

Here is the attribute code:

   1:  public class AdminAuthorizeAttribute : ActionFilterAttribute
   2:  {
   3:      public override void OnActionExecuting(ActionExecutingContext filterContext)
   4:      {
   5:          if (!filterContext.HttpContext.User.Identity.IsAuthenticated
   6:              || !filterContext.HttpContext.User.IsInRole("Admin"))
   7:          {
   8:              filterContext.Result = new RedirectResult("Your custom LogOn URL (translated, etc.)");
   9:          }
  10:      }
  11:  }

And here is the new controller code:

   1:  [AdminAuthorize]
   2:  public class AdministrationController : Controller
   3:  {
   4:      public ActionResult Index()
   5:      {
   6:          return View();
   7:      }
   8:      
   9:      [........]
  10:  }


No comments:

Post a Comment

Note: Only a member of this blog may post a comment.