ASP.NET MVC 中的自定义安全方案
本文关键字:自定义 安全 方案 NET MVC ASP | 更新日期: 2023-09-27 18:32:25
我在这方面没有太多经验,我真的希望从你们那里得到一个好的建议。我需要实现以下安全方案,我想知道最好的方法。
想象一下,我们有员工、主管和部门经理。员工和主管都根据并指向他们所属的部门经理分配经理 ID。
当主管用户登录时,我希望他只能看到与其属于同一 ManagerId 的员工的记录。如果另一个主管有另一个 ManagerId 用户登录并在 url 中手动打孔其他员工的信息(例如:wwww.domain.com/employee/details/{id} ),因为他的经理 ID != 员工的经理 ID 我希望访问受到限制。
有意义吗?
我开始输入所有操作方法的检查,例如:
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
}
}
但是在所有操作方法中键入它似乎是多余的和公正的。呃......我知道一定有更好的方法。
这是一个解决方案的尝试。 它需要一些清理,但应该给你你需要的一切。
创建自定义操作筛选器,然后用它修饰方法。
[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,因此我将有其他方法/参数来指定操作的基本性质(例如读取,写入,删除,创建等)。