Как установить аутентификацию во время выполнения в ASP.NET Core? - PullRequest
6 голосов
/ 07 ноября 2019

Я создаю приложение, в котором есть управление модулями на основе ролей, и оно меняется в любое время и в любое время. Сценарий:

  • Если у пользователя есть доступ к созданию и просмотру Employee, то пользователь может только создавать и просматривать сотрудников, но в будущем администратор меняет роль пользователя с создания и просмотра на просмотр и удаление, чем пользователь можеттолько выполняйте это действие.

Я пытаюсь с помощью [Authorize(Roles ="Staff")], но если администратор изменит время выполнения, чем это не удается.

Может кто-нибудь разобраться в этом и вернуться ко мне?

1 Ответ

0 голосов
/ 14 ноября 2019

Это сложный вопрос, и нет правильного ответа, но есть несколько способов сделать это. Сначала я буду предполагать, что вы используете аутентификацию без сохранения состояния с использованием 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);
            }
        }

    }

Но это решение не так эффективно, потому что оно требует обращения к базе данных при каждом запросе. Это хорошо для небольших нагрузок, но может создать проблемы в движении. Другой способ - повторно вызывать все пользовательские токены при смене ролей, но это очень сложно. Я уверен, что если вы создадите хранилище быстрого доступа для таких ролей, как redis, проблем с проверкой каждого вызова не возникнет. Также я не рекомендую создавать свое собственное хранилище для пользователей, потому что это кошмар, который нужно поддерживать и постоянно обновлять в соответствии со стандартами безопасности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...