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

我最近主持开发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方法。

您可以创建自己的自定义属性,该属性inheritance自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传递给属性。 但是,您可以通过QueryString属性或Form属性访问filterContext.HttpContext.Request的参数,具体取决于您传递值的方式。 我已适当更新了代码示例。

可以在此处找到更完整的示例

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

  var allowedUsers = new List(); //populate allowedUsers from DB If (User.IsInRole("Update") || allowedUsers.Contains(User.Identity.Name)) { //authorized } 

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

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

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

当我覆盖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; }