Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC 3 dynamic authorization of multiple roles and users

Tags:

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.

like image 321
Anton Gildebrand Avatar asked Jun 19 '11 18:06

Anton Gildebrand


2 Answers

You can create your own custom attribute that inherits from AuthorizeAttribute and override the OnAuthorize method to do what you need.

This should get you started:

public class ArticleAuthorizeAttribute : AuthorizeAttribute
{
    public enum ArticleAction
    { 
        Read,
        Create,
        Update,
        Delete
    }

    public ArticleAction Action { get; set; }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        //do custom authorizization using Action and getting ArticleID 
        //from filterContext.HttpContext.Request.QueryString or
        //filterContext.HttpContext.Request.Form
    }
}

The usage would look like this:

[ArticleAuthorize(Action=ArticleAuthorizeAttribute.ArticleAction.Update)]

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.Request through the QueryString property or the Form property, 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:

        var allowedUsers = new List<string>();
        //populate allowedUsers from DB

        If (User.IsInRole("Update") || allowedUsers.Contains(User.Identity.Name))
        {
            //authorized
        }

Alternatively, you can do both checks against the DB directly in a single method to keep from making two calls.

like image 160
Jimmie R. Houts Avatar answered Sep 20 '22 15:09

Jimmie R. Houts


Here's a much easier way to accomplish the same thing:

[Authorize]
public ActionResult UpdateArticle(ArticleModel model, int articleid)
{
    // if current user is an article editor
    return View();
    // else
    return View("Error");
}
like image 38
David Wick Avatar answered Sep 21 '22 15:09

David Wick