在ASP.NET MVC自定义安全方案(Custom security scenario in AS

2019-10-16 15:18发布

我没有很多这方面的经验,我真的很希望能够从你们那里得到了很好的建议。 我需要实现以下安全的情况,我想知道做到这一点的最好办法。

试想一下,我们有员工,主管和部门经理。 员工和监事基于关闭,指着他们所属的部门经理已经理ID分配。

当我上司用户登录想让他只能看到属于同一经理ID作为他的员工记录。 如果与另一个经理ID用户登录并手动其他主管拳打其他员工在URL信息!(例如:wwww.domain.com/employee/details/{id}),因为他的经理ID =雇员的经理ID,我想访问受到限制。

是否有意义 ?

我开始对所有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打字说出来似乎是多余的和just..ehh ......我知道必须有一个更好的办法。

Answer 1:

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

创建自定义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.
        }
    }
}


Answer 2:

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

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的,我想有更多的方法/参数指定动作的基本性质(例如,读,写,删除,创建等)。



文章来源: Custom security scenario in ASP.NET MVC