在 Web Api、服务层、数据库中检查用户访问的更好方法
Better approach to check users access in Web Api, Service layer, DB
用户被分配到一个或多个部门。
用户有一个或多个角色,例如,Read Own角色只能查看his/her任务。虽然 团队成员 角色可以查看和编辑部门 he/she 分配给的其他任务。
角色为 Admin 的用户可以查看和编辑系统中的所有任务。
由于防止未经授权的访问和性能原因,我们希望将当前登录的用户 ID 一直传递到数据库,以便只能获取 he/she 有权访问的记录。
我们的系统设计是:
Web API -> Business/Service 层 -> 存储库 -> DB
目前,我们在每个方法中将用户 ID 从 Web API 传递到服务层,例如检查用户是否具有角色 团队成员(谁可以 view/edit 其他用户 他有权访问的部门内的任务)
并获取他有权访问的所有部门,然后将其进一步传递给存储库。
是否有更好的方法来避免在每个方法中传递用户 ID?
上述设计中检查用户访问权限的最佳位置是什么?
理想情况下,我们希望没有用户 ID 参数的方法能够使用相同的 类 在另一个应用程序中进行报告。
有什么想法吗?
有一个安全层(由装饰您的服务层 class 的 class 组成)检查用户是否有权提出请求。
例如,如果您的 Web API 调用是 ../viewTask/456
检查用户是否是管理员,任务所属部门的团队成员,或者它是否是 his/her 自己的任务。
如果访问控制检查通过,则装饰器 class 会向下传递到包装服务层 class,如果失败则引发未授权异常。
类似...
public class SecuredTaskController : ApiController
{
private IContext _context;
private ITaskService _taskService;
// other services needed for access check (eg. userService?)
public SecuredTaskController(ITaskService taskService, IContext context
// other services needed for access check (eg. userService?)
)
{
_taskService = taskService;
_context = context;
}
public IHttpActionResult Get(Task task)
{
if (hasGetAccess(task, _context.UserId))
return Ok(_taskService.Get(task));
else
return Unauthorized();
}
private bool hasGetAccess(Task task, long userId)
{
// check if userId has acces to get task
}
}
使用依赖项注入将一些 ICurrentUser
实例注入需要用户 ID 来执行查询和其他任务的服务。
public interface ICurrentUser
{
int UserId { get; }
}
public class AspNetCurrentUser : ICurrentUser
{
public int UserId { get { return HttpContext.Current.User.GetUserId<int>(); } }
}
public class Service : IService
{
private readonly ICurrentUser _currentUser;
public Service(ICurrentUser currentUser)
{
_currentUser = currentUser;
}
public object WorkWithUserId()
{
return _currentUser.UserId;
}
}
用户被分配到一个或多个部门。
用户有一个或多个角色,例如,Read Own角色只能查看his/her任务。虽然 团队成员 角色可以查看和编辑部门 he/she 分配给的其他任务。 角色为 Admin 的用户可以查看和编辑系统中的所有任务。
由于防止未经授权的访问和性能原因,我们希望将当前登录的用户 ID 一直传递到数据库,以便只能获取 he/she 有权访问的记录。
我们的系统设计是:
Web API -> Business/Service 层 -> 存储库 -> DB
目前,我们在每个方法中将用户 ID 从 Web API 传递到服务层,例如检查用户是否具有角色 团队成员(谁可以 view/edit 其他用户 他有权访问的部门内的任务) 并获取他有权访问的所有部门,然后将其进一步传递给存储库。
是否有更好的方法来避免在每个方法中传递用户 ID? 上述设计中检查用户访问权限的最佳位置是什么?
理想情况下,我们希望没有用户 ID 参数的方法能够使用相同的 类 在另一个应用程序中进行报告。
有什么想法吗?
有一个安全层(由装饰您的服务层 class 的 class 组成)检查用户是否有权提出请求。
例如,如果您的 Web API 调用是 ../viewTask/456
检查用户是否是管理员,任务所属部门的团队成员,或者它是否是 his/her 自己的任务。
如果访问控制检查通过,则装饰器 class 会向下传递到包装服务层 class,如果失败则引发未授权异常。
类似...
public class SecuredTaskController : ApiController
{
private IContext _context;
private ITaskService _taskService;
// other services needed for access check (eg. userService?)
public SecuredTaskController(ITaskService taskService, IContext context
// other services needed for access check (eg. userService?)
)
{
_taskService = taskService;
_context = context;
}
public IHttpActionResult Get(Task task)
{
if (hasGetAccess(task, _context.UserId))
return Ok(_taskService.Get(task));
else
return Unauthorized();
}
private bool hasGetAccess(Task task, long userId)
{
// check if userId has acces to get task
}
}
使用依赖项注入将一些 ICurrentUser
实例注入需要用户 ID 来执行查询和其他任务的服务。
public interface ICurrentUser
{
int UserId { get; }
}
public class AspNetCurrentUser : ICurrentUser
{
public int UserId { get { return HttpContext.Current.User.GetUserId<int>(); } }
}
public class Service : IService
{
private readonly ICurrentUser _currentUser;
public Service(ICurrentUser currentUser)
{
_currentUser = currentUser;
}
public object WorkWithUserId()
{
return _currentUser.UserId;
}
}