如何在ASP.NET Core中设置运行时身份验证?

Dee*_*oni 8 c# authentication asp.net-mvc asp.net-core

我正在创建一个应用程序,其中存在基于角色的模块管理,并且可以随时对其进行更改。场景:

  • 如果用户有权创建和查看员工,则该用户只能创建和查看员工,但在将来的管理员中,用户从创建,查看,查看和删除的角色更改只能由该用户执行。

我尝试使用,[Authorize(Roles ="Staff")]但是如果管理员更改了运行时,则无法对其进行管理。

有人可以调查一下并回到我身边吗?

Fil*_*das 2

这是一个复杂的问题,没有正确的答案,但有几种方法可以做到。首先,我假设您使用基于声明的 jwt 使用无状态身份验证,最简单的方法是编写自己的策略,该策略将在每个请求之前读取用户角色,这是最简单的方法,也是最快实现的方法。

internal class DatabaseRoles : IAuthorizationRequirement
    {
        public string Role { get; }

        public DatabaseRoles(string role)
        {
            Role = role;
        }
    }

    internal class DatabaseRolesHandler : AuthorizationHandler<DatabaseRoles>
    {
        private readonly UserManager<IdentityUser> userManager;

        public DatabaseRolesHandler(UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager)
        {
            this.userManager = userManager;
        }

        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, DatabaseRoles requirement)
        {
            //NOTE this is the out of the box implementation of roles and simple query to get the roles from the EF backed database. I would recoment makeing a custom privelages store for this and not using roles for this but access rights
            var user = await userManager.FindByIdAsync(userManager.GetUserId(context.User));
            if (await userManager.IsInRoleAsync(user, requirement.Role))
            {
                context.Succeed(requirement);
            }
        }

    }
Run Code Online (Sandbox Code Playgroud)

但该解决方案的性能并不高,因为它需要在每个请求上调用数据库。这对于小负载来说没问题,但可能会造成流量问题。另一种方法是在角色发生变化时撤销所有用户令牌,但这非常复杂。我确信,如果您为像 redis 这样的角色创建一些快速访问存储,那么对每次调用进行检查都不会出现问题。另外,我不建议创建您自己的用户存储,因为维护和保持最新的安全标准是一场噩梦。