0

我有以下内容:-

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

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

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

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

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 方法上,我将通过调用 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”);

因此,任何人都可以建议我的方法是否有效,否则会导致我不知道的问题。问候

4

2 回答 2

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)    
{
    //..
}

让我知道这是否适合您。

于 2013-07-04T10:13:55.263 回答
1

您采用的方法看起来很合理,但我会添加一些更改:

  1. 如果您忘记调用 HaveReadPermision 方法怎么办?从 Actions 检查授权也不是最干净的解决方案,这不是 Action 的责任。

最好单独保留授权逻辑。例如,您可以在存储库上创建一个装饰器,它将检查当前用户的权限:

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 返回当前用户名。进行更改后,您在编写操作时无需担心授权

于 2013-07-04T10:20:11.193 回答