The MVC platform: integrating authentication and authorization in your apps
Today we’ll keep looking at the MVC framework and will see how the you can integrate authentication and authorization in your MVC applications. As we all know, authorization and authentication are different things, but they’re “connected”. I say this because whenever you need to decide if a user can execute a specific operation (ie, whenever you think in authorization), the first thing you need to ensure is that you “know” who the current user is (ie, you have already authenticated the user).
The traditional ASP.NET engine already has some infrastructure in place for performing these operations, but you can’t really reuse the same approaches with MVC. To understand why, you just need to remember that in web forms, you access pages and those are the resources that are protected. With MVC, you’re accessing controller’s actions and that is what you need to protect.
Despite these differences, you can still reuse the available web forms authentication framework based on the “old” FormAuthentication class for authenticating a user and making that info available for future requests. In fact, if you look at the default code generated by the MVC template, you’ll notice that it already is using that class for authenticating a user.
Ok, now we’re ready to go into authorization. In MVC, you can apply authorization to an action based on username or on group. If you don’t pass any information for those options, then it will only let authenticated users access the protected resource (independent of the its username or associated groups). You use attributes (based on filters) to specify this info, more specifically, instances of AuthorizeAttribute class. If you don’t recall how filters work, probably now is a good time to refresh your memory.
Internally, the class will get the IPrincipal for the user from the current context (recall that MVC apps work over some abstractions which end up delegating to the traditional ASP.NET web forms classes) and then it will see if the user is on the list of users defined and/or if the user belongs to any of the roles passed to the attribute. Here’s an example of how you can use this attribute and apply it to an action:
[Authorize(Users = "luis, john", Roles = "group1, group2")]
public ActionResult Index()
with the previous snippet, you’ll have to be authenticated as luis or john and you must also belong to group1 or group2 in order to execute the Index action (do notice that if you specify both options, then the current user needs to satisfy both of them).
Before ending, there’s still time to mention an interesting detail: in order to guarantee that the action is only executed by authorized users, the class ends up hooking the validation callback performed by the cache. This is an important detail because cache checking is performed before the code on the controller is run and if this hook wasn’t set up, then it would be possible for a non authorized user to get a page that was recently viewed by another authorized user.
And that’s all for today. Keep tuned for more on the MVC framework.