ASP.NET MVC中的自定义安全场景

我没有太多的经验,我真的希望能从你们那里得到一个很好的建议。 我需要实施以下安全方案,并希望了解实现方案的最佳方法。

想象一下,我们有员工,主管和部门经理。 员工和主管都将ManagerId分配给他们所属的部门经理并指向他们所属的部门经理。

当主管用户登录时,我希望他只能看到属于与他相同的ManagerId的员工的记录。 如果另一个管理员与另一个ManagerId用户登录并手动在URL中冲出其他员工的信息(例如:wwww.domain.com/employee/details/{id}),因为他的ManagerId!=员工的ManagerId,我希望访问受到限制。

是否有意义 ?

我开始对所有ActionMethods输入检查,例如:

public ActionResult Details(int id)
{
    var employee = employeeRepository.Get(id)
    var user = (CustomIdentity)ControllerContext.HttpContext.User.Identity;

    if(employee.managerId == user.managerId)
    {
        Do whatever...
    }   
    else    
    {
        Not allowed
    }
}

但在所有的ActionMethods中输入这些信息似乎是多余的,只是..呃......我知道必须有更好的方法。


这是一个解决方案的刺。 它需要一些清理,但应该给你你需要的一切。

创建一个自定义的ActionFilter,然后用它装饰你的方法。

[ManagerIdAuthentication]
public ActionResult Details(int id)
{
     // Gets executed if the filter allows it to go through.
}

下一个课程可以在单独的库中创建,因此您可以将其包含在需要此验证的所有操作中。

public class ManagerIdAuthentication : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // the next line needs improvement, only works on an httpGet since retrieves
        // the id from the url.  Improve this line to obtain the id regardless of 
        // the  method (GET, POST, etc.)
        var id = filterContext.HttpContext.Request.QueryString["id"];

        var employee = employeeRepository.Get(id);
        var user = filterContext.HttpContext.User.Identity;
        if (employee.managerId  == user.managerId)
        {
            var res = filterContext.HttpContext.Response;
            res.StatusCode = 402;
            res.End();
            filterContext.Result = new EmptyResult();  //may use content result if want to provide additional info in the error message.
        }
        else
        {
            // OK, let it through.
        }
    }
}

过去我有类似的问题,我会考虑每个对象的权限。 我所做的是将一个成员添加到对象类似于:

public bool CanUserAccess(User user) {
    return managerId == user.managerId;
}

然后,在每个可以访问受控资源的操作的顶部:

public ActionResult Details(int id)
{
    var employee = employeeRepository.Get(id)
    var user = (CustomIdentity)ControllerContext.HttpContext.User.Identity;
    if(!employee.CanUserAccess(user))
        return new HttpUnauthorizedResult();

    // Normal logic here
}

这当然不是完美的,但它确实集中了权限处理,并允许您轻松地增加未来的复杂性(允许访问链,人力资源的特殊规则等)。 您还可以编写另一个重载/扩展来访问User.Identity属性以获得更多自动化(或者至少处理类型转换)。

由于我正在处理ACL,因此我会使用其他方法/参数来指定动作的基本属性(例如读取,写入,删除,创建等)。

链接地址: http://www.djcxy.com/p/90175.html

上一篇: Custom security scenario in ASP.NET MVC

下一篇: ASP.NET 5 Handling Permissions with Authorize Attribute