根据用户请求访问的组织修改 .NET Core 角色(按请求)

Modifying .NET Core Roles depending on which organization the user is requesting access to (per-request)

我有一个用例,其中 .NET Core API 的用户可以属于多个 "organizations" 并且在这些组织中具有不同的角色。

例如,如果他们代表 OrganizationId = 1 POST 到 Location/Create 端点,则他们应该具有管理员权限。但是,如果他们尝试代表 OrganizationId = 2 访问该端点,则他们应该只有基本用户权限。用户无需注销并重新登录即可执行这些操作。

我想编写一些中间件来进行数据库调用并检索用户在他们试图修改的组织中的角色,然后在控制器上使用 .NET Core 角色语法来限制该级别的访问。

我无法找到这样一个例子,即在请求管道到达控制器操作之前,中间件会在每个请求上修改用户角色。有没有人有过类似的身份验证方案的经验?

您是否考虑过在数据库中保留一个权限模型,为每个组织映射给定用户的角色,而不是修改用户在中间件中的角色?然后,您可以 allow/deny 根据请求的域和该域中用户的权限级别在中间件中请求。

例如,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      |
------------------------------------------------

并且您将有一个单独的 table 包含角色权限,如下所示:

Role
-------------------------------------
| RoleId | Name  | CanGet | CanPost |
|-----------------------------------|
| 1      | Admin | True   | True    |
| 2      | Basic | True   | False   |
-------------------------------------

使用此模型,您可以在中间件中查询这些 table 以确定适当的访问级别。

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;
        }
    }
}