使用对象帮助程序方法实现授权规则

时间:2013-07-04 09:04:35

标签: asp.net asp.net-mvc roleprovider

我有以下内容: -

  1. 我正在使用Asp.net MVC4启用Windows身份验证的资产管理系统。

  2. 系统允许指定一组用户可以执行的操作(例如,某些组可以拥有添加新物理资产的权限,而他们只能读取某些逻辑资产,等等)。

  3. 所以我发现使用内置的Asp.net角色管理,不会让我拥有我想要的灵活性。所以我决定做以下事情: -

    • 我创建了一个名为“group”的表,代表用户组。用户存储在活动目录中的位置。
    • 我创建了一个名为“安全角色”的表,该表指示每个资产类型对每种资产类型(编辑,添加,删除或查看)的权限级别。
    • 然后在每个操作方法上,我将使用Helper方法来实现并检查某些用户是否在具有所需权限的相关组中,例如
  4. Car model object我将创建一个新的辅助方法

    Public bool HaveReadPermison(string userName) {
    
    //check if this user is within a group than have Read permission on CARS, //OR is within a GROUP THAT HAVE HIGHER PERMISON SUCH AS EDIT OR ADD OR //DELETE. 
    } 
    

    接下来,在Action方法中,我将通过调用操作方法来检查用户是否具有读取权限: -

    public ActionResult ViewDetails(int id) { // to view transportation asset type
    Car car = repository.GetCar(id);
    if (!car.HaveReadPermision(User.Identity.Name)) {
    if (car == null)
    return View("NotFound");
    else
    return View(car);
    }
    else
    return view (“Not Authorized”);
    

    如果我的方法有效或者它会引起我不知道的问题,那么任何人都可以提出建议。 此致

2 个答案:

答案 0 :(得分:1)

在我看来,一旦您决定使用ASP成员资格和角色提供者,您可以继续利用它们进行授权,只需使用Authorize属性即可。这也将允许通过用户名和角色限制访问。

该属性不会执行基于操作的授权。在这种情况下,有一些选项,但在我看来,松散地基于以下代码可以通过自定义操作过滤器轻松解决:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CheckUserPermissionsAttribute : ActionFilterAttribute
{
    public string Model { get; set; }
    public string Action { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var user = filterContext.HttpContext.User.Identity.Name; // or get from DB 

        if (!Can(user, Action, Model)) // implement this method based on your tables and logic
        {
            filterContext.Result = new HttpUnauthorizedResult("You cannot access this page");
        }

        base.OnActionExecuting(filterContext);
    }
}

是的,它模糊地启发了CanCan,这对于这类事物来说是一个很好的Ruby宝石。

如果指定了登录页面,则返回Unauthorized (401)还将指示您的服务器重定向到登录页面。如果要在其他位置重定向,可能需要处理该逻辑。在这种情况下,你应该这样做:

filterContext.Result = new RedirectToRouteResult(new System.Web.Routing.RouteValueDictionary { { "Controller", "Home" }, { "Action", "Index" } });

并选择适当的控制器/操作对。

您可以使用以下属性:

[CheckUserPermissions(Action = "edit", Model = "car")]
public ActionResult Edit(int id = 0)    
{
    //..
}

请告诉我这是否适合您。

答案 1 :(得分:1)

您采取的方法看似合理,但我会添加一些更改:

  1. 如果您忘记拨打HaveReadPermision方法怎么办?从Actions中检查自动化也不是最干净的解决方案,这不是Action的可行性。
  2. 最好分开保存授权逻辑。例如,您可以在您的存储库上创建一个装饰器,它将检查当前用户的权限:

    public class AuthorizationDecorator: IRepository
    {
         public AuthorizationDecorator(IRepository realRepository, IUserProvider userProvider)
         {
            this.realRepository = realRepository;
            this.userProvider = userProvider;
         }
    
        public Car GetCar(int id) 
        {
           if(this.UserHaveReadPermission(this.userProvider.GetUserName(), Id))
           {
              return this.realRepository.GetCar(id);
           }
           else
           {
               throw new UserIsNotAuthorizedException();
           }
        }
    
        private bool UserHaveReadPermission(string username, int id)
        {
          //do your authorization logic here
        }
    }
    

    IUserProvider将从httpRequest返回curent用户名。 在进行更改后,您无需在编写操作

    时担心授权