【问题标题】:MVC 3 dynamic authorization of multiple roles and usersMVC 3 多角色和用户的动态授权
【发布时间】:2011-09-18 06:08:23
【问题描述】:

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

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

现在这真的很简单。我只是说只有“管理员”角色的成员才能更新文章。但这只是静态的。所以我在我的数据库中创建了一个凭证表,最后告诉我“第 5 条可以由角色 1、2、3 和 4 以及用户 A、b 和 C 编辑”。到目前为止,一切都很好。但是我将如何使用 Authorize 解决方案来实现呢?

我想做这样的事情:

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您可以创建自己的自定义属性,该属性继承自 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 的参数,具体取决于您传递值的方式。我已经适当地更新了代码示例。

      更完整的例子可以找到here

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

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

      或者,您可以直接在一个方法中对数据库进行两项检查,以避免进行两次调用。

      【讨论】:

      • 谢谢,很有帮助!我将尝试实现这一点,并返回结果!
      • 您好!现在我已经尝试并成功了。使用用户和角色授权时,只授权具有指定角色的指定用户。我希望它是指定的用户,或具有指定角色的用户。这有可能以某种方式解决吗?
      • @Anton,您需要直接查询数据库以获得显式访问。由于您必须直接访问数据库以获得其中的一部分,因此您可能需要编写一个方法,该方法接受用户名、角色和文章 ID,并返回他们是否具有访问权限。 UserCanPerformAction(User.Identity.Name, "Update", 23)
      • 我认为你不明白我的问题是什么,可能是因为我描述得不好 =)。在 OnAuthorizatoin 方法中,如果我写:'Users = "Anton"' 用户 "Anton" 将是唯一有权做某事的人。如果我只写:'Roles="Admin"' 只有“Admin”组中的用户才能做某事。但如果我写:'Users="Anton Roles="Admin"' 用户“Anton”只有在他具有“Admin”角色时才会被授权。但我希望用户 Anton 被授权并且每个具有 Admin 角色的人已授权。
      • @Anton,我想这就是你的意思:) 我已经更新了我的答案,包括一个简短的 sn-p,用于检查用户列表或角色成员资格以获得授权。您需要针对您的情况编写数据库代码(ADO.net、Entity Framework、Linq to SQL 等)
      【解决方案3】:

      这里有一个更简单的方法来完成同样的事情:

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

      【讨论】:

        猜你喜欢
        • 2011-09-03
        • 1970-01-01
        • 1970-01-01
        • 2011-09-29
        • 2014-05-08
        • 2021-09-04
        • 2011-06-02
        • 2010-10-21
        • 2017-12-01
        相关资源
        最近更新 更多