MVC 3动态授权多个角色和用户

时间:2011-06-19 18:17:50

标签: c# asp.net asp.net-mvc-3 authorization

我最近为MVC 3进行了开发,但是从早些时候开始就拥有C#和ASP.NET的经验。所以我将从我想要完成的事情开始。我开发了一个小型网站来托管文章。我已经在网站上实现了基于SQLServer的会员资格管理。现在我想创建一个凭证系统,限制并允许合适的用户创建,删除和更新文章。有一个简单的解决方案就是这样做:

[Authorize(Roles="Admin")]
    public ActionResult UpdateArticle(ArticleModel model, int articleid)
    {
        return View();
    }

现在这很简单。我只是说只允许角色为“Admin”的成员更新文章。但这只是静态的。所以我在我的数据库中创建了一个凭证表,最后告诉我“第5条可以由角色1,2,3& 4和用户A,b& C”编辑。到现在为止还挺好。但是,如何使用授权解决方案实现这一目标?

我想做这样的事情:

[Authorize(getAuthorizedusers("update",this.articleid))]

其中getAuthorizedusers返回哪些用户和角色有权使用传递给它的articleid更新文章。

所以我(至少)有两个问题: - 获取Authorize方法以接受多个用户和角色。 - 将发送到UpdateArticle方法的提供的articleid传递给getAuthorizedusers方法。

3 个答案:

答案 0 :(得分:19)

您可以创建自己继承自AuthorizeAttribute的自定义属性,并覆盖OnAuthorize方法以执行您需要的操作。

这应该让你开始:

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
    }
}

用法如下:

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

编辑:在进一步研究之后,看起来你无法将this.articleID传递给属性。但是,您可以访问filterContext.HttpContext.RequestQueryString属性或Form属性的参数,具体取决于您传递值的方式。我已适当更新了代码示例。

可以找到更完整的示例here

要使用用户角色和用户列表检查授权,您可以执行以下操作:

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

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

或者,您可以在一个方法中直接对DB进行两次检查,以防止进行两次调用。

答案 1 :(得分:2)

这是一种更简单的方法来完成同样的事情:

[Authorize]
public ActionResult UpdateArticle(ArticleModel model, int articleid)
{
    // if current user is an article editor
    return View();
    // else
    return View("Error");
}

答案 2 :(得分:2)

当我覆盖AuthorizeCore方法并授权我想要的方式时,我按照我的意愿工作。

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        IPrincipal user = httpContext.User;
        if (!user.Identity.IsAuthenticated)
        {
            return false;
        }

        if ((_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) && (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)))
        {
            return false;
        }

        return true;
    }