【问题标题】:Dynamic role providing in asp.net mvc (Roles are not fixed It is keep updating)在 asp.net mvc 中提供动态角色(角色不固定,不断更新)
【发布时间】:2014-07-22 04:31:44
【问题描述】:

我知道简单的角色提供者,如果我需要限制特定的操作,我必须简单地编写 Authorize(Roles = "Admin") 或者如果我需要限制视图的特定部分,我需要编写 @if(User. IsInRole(“管理员”))。

但我的问题是,如果我的角色不固定并且存储在数据库中并且我的超级管理员可以编辑和删除它们怎么办。

我的要求是超级管理员可以添加、更新、删除角色,还可以创建不同的用户并维护这些用户的角色。

我做了很多谷歌搜索,发现如下内容

    [AttributeUsage (AttributeTargets.Method|AttributeTargets.Class,Inherited = true,AllowMultiple=true) ]
    public class CustomRole : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase context)
        {
            Respository db = new Respository();
            if (db.UserMasters.Where(x => x.user_name == context.User.Identity.Name).Count() > 0)
            {
                return true;
            }
            else { return false; }
        }
    }

这里我可以使用这个代码来授权动作方法如下

    [CustomRole]
    public ActionResult Details(int id = 0)
    {
        Employee employee = db.Employees.Find(id);
        if (employee == null)
        {
            return HttpNotFound();
        }
        return View(employee);
    }

这里我的这个操作方法是受保护的,但是如果我想通过这个自定义方法保护视图的某些部分怎么办。如何使用这个功能来实现作为 User.IsInRole("Admin") 的功能?

【问题讨论】:

  • 如果您的角色未预定义,您希望如何针对它们编写代码?您是否希望管理员将哪些部分可见为可配置选项?
  • 是的,exactly.admin 将决定哪个模块对哪个用户角色可见。我的应用程序中现在共有三个模块。

标签: asp.net asp.net-mvc-3 asp.net-mvc-4 razor asp.net-mvc-5


【解决方案1】:

完全回答您的问题可能超出了 StackOverflow 的范围,因为它基本上需要为您编写大部分应用程序,但这是总体思路。

编写一个类似这样的辅助类:

public class ModuleHelper
{
    public static bool UserCanAccessModule(string moduleIdentifier)
    {
        bool canAccess = false;

        /* 
            Call into your service with current User.Name and module identifier (integer, GUID, whatever).
            Return result of whether user has the required role for the specified module
        */
        try
        {
            canAccess = service.CanUserAccessModule(User.Identity.Name, moduleIdentifier);
        }
        catch
        {
            // catching all exceptions, since this is a UI helper
        }       

        return canAccess;
    }

    // etcetera...
}

我建议将它包装在应用程序的根命名空间中;否则,在Views 文件夹中web.configsystem.web.webPages.razor 部分中添加对此类命名空间的引用。然后,您可以执行以下操作:

<div class="col-sm-3 col-md-2 sidebar">
    @if (ModuleHelper.UserCanAccessModule("moduleXYZ"))
    {
        @Html.Action("moduleXYZ")
    }
</div>

这显然假设很多,但这个想法在实践中并不新鲜或那么复杂。服务的逻辑比较简单:

  1. 查找用户
  2. 查找“动作”或“模块”
  3. 在分配给每个角色的角色之间寻找交集(如果有的话)。

没有交集意味着用户没有所需的角色。

【讨论】:

    【解决方案2】:

    您的要求将分 3 步完成

    1- 创建所有默认角色,将其存储在 database.i.e-roleid,rolename 2-使用角色标识创建新用户映射用户标识时。 3-还为您必须给予的所有许可制作一张表格。 4-为管理员制作单独的用户界面以更改每个用户的角色。 数据库将如下图所示。

    和 ui 将是这样的。

    你自己试试吧..

    【讨论】:

      【解决方案3】:

      Tieson T. 已经为您的问题提供了很好的答案,因此如果您想将所有授权步骤都保留在控制器中,我将在此处提供一种替代方法。

      考虑将主视图的不同方面(或受限部分)分离为执行受限功能的部分视图(或多个视图)。然后,您可以使用RenderAction Html Helper 将您的部分设置为从使用ChildActionOnly 属性修饰的控制器操作返回,而不是使用:@Html.RenderPartial("ViewName", Model)

      例如:

      <div class="col-sm-3 col-md-2 sidebar">
          @Html.RenderAction("RestrictedContent")
      </div>
      

      然后在你的控制器类中

      public class RestrictedController : Controller {
      
          public RestrictedController() : base() {
      
          }
      
          [ChildActionOnly()]
          [CustomRole()]
          public ActionResult RestrictedContent() {
              return PartialView("RestrictedPartial");
          } // end action RestrictedContent
      
      } // end class
      

      这种方法的唯一考虑是在您的自定义属性中询问IsChildAction 属性以避免呈现重定向或在用户未授权的情况下您的属性所做的任何事情,因为您可能不想渲染任何东西。

      例如(在您的自定义属性类中):

      public override void OnAuthorization(AuthorizationContext filterContext) {
          if(filterContext.IsChildAction) {
              filterContext.Result = new EmptyResult(); // return an empty result instead of performing a redirect.
          } else {
              base.OnAuthorization(filterContext); // continue with custom authorization if it is not a child action
          } // end if/else
      } // end method OnAuthorization
      

      Phil Haack 在这里有一篇文章描述了 RenderAction 方法的用法:http://haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx/

      此外,有关ActionRenderAction 之间差异的有趣讨论,请参见此处。 The difference between Html.Action and Html.RenderAction

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-15
        • 1970-01-01
        • 1970-01-01
        • 2011-04-18
        • 1970-01-01
        • 2011-01-01
        • 1970-01-01
        相关资源
        最近更新 更多