I recently starded developing for MVC 3 but have experience in both C# and ASP.NET since earlier. So i’ll start with what i’m trying to accomplish. I’ve developed a small site for hosting articles. I’ve implemented SQLServer based membership managament to the site. Now i want to create a credentials system that restricts and allows the right users to create, delete and update articles. There is one simple solution to this and that is to do it like this:
[Authorize(Roles="Admin")]
public ActionResult UpdateArticle(ArticleModel model, int articleid)
{
return View();
}
Now this is really simple. I simply say that only members that are in the role “Admin” are allowed to update an article. But that’s just to static. So i created a credentials table in my database that in the end tells me that “Article 5 can be edited by roles 1,2,3 & 4 and by users A, b & C”. So far so good. But how would i implement that with the Authorize solution?
I would like to do something like this:
[Authorize(getAuthorizedusers("update",this.articleid))]
where getAuthorizedusers returns which users and roles are authorized to update the article with the articleid that was passed to it.
So I have (at least) two problems here:
-Getting the Authorize method to accept multiple users and roles.
-Passing the supplied articleid, that was sent to the UpdateArticle method, to the getAuthorizedusers method.
You can create your own custom attribute that inherits from
AuthorizeAttributeand override theOnAuthorizemethod to do what you need.This should get you started:
The usage would look like this:
Edit: After looking into this a bit more, it looks like you can’t pass this.articleID in to the attribute. However, you do have access to the parameters from
filterContext.HttpContext.Requestthrough theQueryStringproperty or theFormproperty, depending on how you are passing the values. I have updated the code sample appropriately.A more complete example can be found here
To check for authorization using user role and user list you would do something like this:
Alternatively, you can do both checks against the DB directly in a single method to keep from making two calls.