我有一个用例,我们的.NET Core API用户可以属于多个“组织”,并且在这些组织中具有不同的角色。
例如,如果他们代表OrganizationId = 1 POST到“位置/创建”端点,则应具有“管理员”特权。但是,如果他们尝试代表OrganizationId = 2访问该端点,则它们应仅具有基本用户特权。用户可以执行这些操作,而无需注销并再次登录。
我想编写一些中间件来进行数据库调用,并为他们试图修改的组织中的用户检索角色,然后在控制器上使用.NET Core Role语法在该级别上限制访问。
我找不到一个示例,其中中间件在每个请求的请求管道到达控制器动作之前修改了用户角色。有没有人有过类似的身份验证方案的经验?
答案 0 :(得分:2)
您是否考虑过在数据库中保留一个权限模型来为每个组织映射给定用户角色,而不是在中间件中修改用户角色?然后,您可以根据所请求的域和该域中用户的权限级别来允许/拒绝中间件中的请求。
例如,John Smith属于两个ID为1和2的组织。用户许可权模型可能如下所示:
UserPermissionLevel
------------------------------------------------
| Uid | Name | OrganizationId | RoleId |
|----------------------------------------------|
| 1 | John Smith | 1 | 1 |
| 1 | John Smith | 2 | 2 |
| 2 | Jane Doe | 2 | 1 |
------------------------------------------------
您将有一个单独的表,其中包含Role权限,如下所示:
Role
-------------------------------------
| RoleId | Name | CanGet | CanPost |
|-----------------------------------|
| 1 | Admin | True | True |
| 2 | Basic | True | False |
-------------------------------------
使用此模型,您可以在中间件中查询这些表以确定适当的访问级别。
public class OrgAuthorizationMiddleware
{
...
public async Task Invoke(HttpContext context, MyDbContext databaseContext)
{
// Check that the user has the requested role and the
// appropriate permission for the request as needed.
// Add additional request type logic to check user's
// specific permissions from UserPermissionLevel.
if databaseContext.Role.Any(x => x.RoleId, RoleId)
{
await _next.Invoke(context);
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
}
}