Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET MVC中的自定义安全方案_C#_Asp.net Mvc_Security_Authentication - Fatal编程技术网

C# ASP.NET MVC中的自定义安全方案

C# ASP.NET MVC中的自定义安全方案,c#,asp.net-mvc,security,authentication,C#,Asp.net Mvc,Security,Authentication,我在这方面没有太多的经验,我真的希望你们能给我一个好的建议。我需要实现以下安全场景,我想知道最好的方法 假设我们有员工、主管和部门经理。 员工和主管都根据他们所属的部门经理指定了ManagerId 当主管用户登录时,我希望他只查看与他属于同一ManagerId的员工的记录。 如果另一个主管与另一个ManagerId用户登录并手动在url ex:wwww.domain.com/employee/details/{id}中输入其他员工的信息, 因为他的经纪人员工的经理我希望访问受到限制 这有意义吗

我在这方面没有太多的经验,我真的希望你们能给我一个好的建议。我需要实现以下安全场景,我想知道最好的方法

假设我们有员工、主管和部门经理。 员工和主管都根据他们所属的部门经理指定了ManagerId

当主管用户登录时,我希望他只查看与他属于同一ManagerId的员工的记录。 如果另一个主管与另一个ManagerId用户登录并手动在url ex:wwww.domain.com/employee/details/{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中输入这些似乎是多余的,只是..呃。。。我知道必须有更好的方法。

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

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
}
它当然不是完美的,但它确实集中了权限处理,并允许您在将来轻松增加复杂性—允许访问链、HR的特殊规则等。。您还可以编写另一个重载/扩展来访问User.Identity属性,以实现更高的自动化程度,或者至少处理类型转换


因为我在处理ACL,我将有另外的方法/参数来指定动作的基本性质,例如读、写、删除、创建等。

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

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
}
它当然不是完美的,但它确实集中了权限处理,并允许您在将来轻松增加复杂性—允许访问链、HR的特殊规则等。。您还可以编写另一个重载/扩展来访问User.Identity属性,以实现更高的自动化程度,或者至少处理类型转换


因为我处理的是ACL,所以我会有额外的方法/参数来指定操作的基本性质,例如读、写、删除、创建等。

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

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

这里有一个解决办法。它需要一点清理,但应该给你你需要的一切

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

除了把IF逻辑放到一个单独的语句中,基本上是一样的。只是将权限检查集中起来,这样就比较干燥了。假设ActionFilterAttribute方法可以在您的应用程序中工作,那么它可能是最干净的方法。您需要能够访问存储库,这并不难,但您还需要能够解码用于访问检查的对象,这可能更具挑战性。除了将我的IF逻辑用于单独的语句之外,基本上是一样的。只是将权限检查集中起来,这样就比较干燥了。假设ActionFilterAttribute方法可以在您的应用程序中工作,那么它可能是最干净的方法。您需要能够访问存储库,这并不难,但您还需要能够解码用于访问检查的对象,这可能更具挑战性。感谢您的回复。非常有趣。我真的需要其他东西吗?我不能说Ifemployee.managerId!=user.managerId抛出新的MyUnauthorizedException。。。。。。。。。。。否则将触发实现此功能的方法。不我错过了什么?if employee.managerId==user.managerId语句中的内容有什么意义?不需要else。。。只是为了说明它将继续执行。谢谢你的回复。非常有趣。我真的需要其他东西吗?我不能说Ifemployee.managerId!=user.managerId抛出新的MyUnauthorizedException。。。。。。。。。。。否则将触发实现此功能的方法。不我错过了什么?if employee.managerId==user.managerId语句中的内容有什么意义?不需要else。。。只是为了说明它将继续执行。