Использование JWT с авторизацией на основе ролей - PullRequest
0 голосов
/ 22 мая 2018

Фон

Я работаю над веб-приложением, использующим Spring Security, и впервые пытаюсь использовать веб-токены JSON для аутентификации.Приложение должно ограничивать доступ к определенным URI на основе пользовательских ролей.Он должен обеспечивать возможность смены пароля и позволять Admin пользователям изменять роли других пользователей.

В учебнике , за которым я следовал, при каждом HTTP-запросе к серверу происходит сбой базы данныхна CustomUserDetailsService чтобы загрузить текущие данные о пользователе, которые кажутся сильно загруженными:

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    //...

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, 
                                    FilterChain filterChain) throws ServletException, IOException {
        try {
            String jwt = getJwtFromRequest(request);

            if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
                Long userId = tokenProvider.getUserIdFromJWT(jwt);

                UserDetails userDetails = customUserDetailsService.loadUserById(userId);
                UsernamePasswordAuthenticationToken authentication = 
                        new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        } catch (Exception ex) {
            logger.error("Could not set user authentication in security context", ex);
        }

        filterChain.doFilter(request, response);
    }

    //...

}

Автор учебного пособия предлагает другой вариант:

Обратите внимание, что вы также можетезакодируйте имя пользователя и роль пользователя в утверждениях JWT и создайте объект UserDetails, проанализировав эти утверждения из JWT.

Однако это усложняет изменение роли пользователя, поскольку у нас нетспособ отбрасывания выданных токенов без их отслеживания.

Возможное решение

Я исследовал тему JWT и предложил следующее решение:

Давайте сохранимимя пользователя и роль в заявках JWT и установка короткого срока действия токена (с использованием заявки exp) - по истечении этого периода, например, 15 минут, мы нажимаем на базу данных, чтобы проверитьk данные пользователя.Если роль изменилась, мы генерируем новый токен с новой ролью в полезной нагрузке.Если пароль был изменен, мы требуем, чтобы пользователь прошел повторную аутентификацию перед созданием нового токена.

Очевидным недостатком этого решения является то, что любое изменение прав доступа пользователя вступает в силу после истечения срока его действия.

Вопрос

Существуют ли другие способы решения этой проблемы?проблема обработки изменения пользовательских данных при использовании JWT?

1 Ответ

0 голосов
/ 22 мая 2018

Мы используем токены JWT с Spring Security и угловым веб-приложением.

Я думаю, что ваша Possible Solution идея верна.Мы справляемся с этим аналогичным образом.Наш поток аутентификации выглядит следующим образом:

  • Пользователь входит в систему по URL-адресу, а заголовок ответа содержит токен JWT
  • токены JWT имеют короткий тайм-аут (в минутах)
  • Через короткое время веб-приложение проверяет сервис «обновить токен», который определяет, является ли токен действительным.Если это так, сервер повторно выдает новый токен, включая все обновленные роли для пользователя, и он затем сохраняется веб-приложением для включения в будущие запросы к бэкэнду.

Из-за обновления«Служба, если роли пользователя изменяются или если они забанены в системе, они будут автоматически замечать новую роль или будут« заблокированы »не позднее времени истечения токена.

Это сработалохорошо для нас в течение многих лет.Роли наших пользователей не часто меняются, и, если когда-либо потребуется, чтобы их роль была немедленно обновлена, они всегда могут выйти / войти обратно.

Дополнительное потенциальное решение

Однако, если крайне важно, чтобы роль пользователя немедленно обновлялась в вашей системе, вы могли бы проверять фильтр Spring на наличие заголовка JWT при каждом запросе, проверять JWT и добавлять новый обновленный JWT.знак на каждый ответ.

Тогда ваш клиент может ожидать получения исправленного токена JWT на каждый ответ от сервера и использовать этот исправленный токен JWT для каждого последующего запроса.

Это будет работать, но будеттакже будет относительно дорогим, если у вас много трафика.

Все зависит от вашего варианта использования.Как я уже сказал, услуга «обновления» хорошо сработала для нас.

...