Как мне обработать запрос в контроллере после успешной аутентификации без сохранения состояния в Spring Security 5 и Spring Boot 2? - PullRequest
0 голосов
/ 06 марта 2020

Я пытаюсь реализовать следующий поток запросов:

  1. Запрос GET отправляется на /api/example с параметрами аутентификации GET
  2. Параметры анализируются в фильтре и генерируются объект аутентификации отправляется на аутентификацию
  3. Поставщик успешно аутентифицирует объект и возвращает его в фильтр
  4. Фильтр пропускает запрос к контроллеру, сопоставленному с /api/example
  5. Контроллер возвращает ответ

Точки с 1 по 3 уже реализованы и работают, метод successfulAuthentication вызывается в фильтре, и нет проблем с передачей запроса обработчику успешной аутентификации. Я уже сталкивался с подобными вопросами (такими как этот ), но большинство из них устарели, используют большую часть конфигурации XML и, что наиболее важно, ответы не применимы к этому варианту использования (обычно некоторые сорт Cook ie и / или токен, как ожидается, будет передаваться между сторонами в обоих направлениях, или контроллер не используется).

Параметры аутентификации являются обязательными и отправляются при каждом запросе, поэтому нет нужды запоминать любые состояния аутентификации за пределами одной области запроса. Другую сторону, отправляющую запрос GET, также не нужно информировать, кроме отправки 401 или возврата ожидаемого ответа.

К сожалению, я не знаю, как достичь пункта 4 в списке выше. Обработчик успеха аутентификации Spring Security пытается перенаправить по умолчанию, что нежелательно, так как оно либо вызывает бесконечное перенаправление l oop (в случае перенаправления на /api/example), либо вызывает совершенно другую часть приложения (в случае значения по умолчанию /).

Конфигурация безопасности HTTP:

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .anonymous().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .csrf().disable();

        http
            .antMatcher("/api/**")
            .addFilterBefore(this.apiAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
            .authorizeRequests()
            .anyRequest()
            .authenticated();
    }

Соответствующий фрагмент из фильтра аутентификации (расширяет AbstractAuthenticationProcessingFilter):

@Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
                                            Authentication authenticationResult) throws IOException, ServletException {
        SecurityContextHolder.getContext().setAuthentication(authenticationResult);

        if (this.eventPublisher != null) {
            eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authenticationResult, this.getClass()));
        }

        this.getSuccessHandler().onAuthenticationSuccess(request, response, authenticationResult);
    }

Существует также пользовательский ApiAuthenticationProvider, но работает без проблем. Я хотел бы избежать любой конфигурации XML и, если возможно, перенаправлений и файлов cookie. Также имейте в виду, что существует несколько сопоставлений для проверки подлинности с одинаковой конфигурацией (например, /api/example, /api/sample ...).

Подходы, которые я уже попробовал:

  1. Перенаправление на URL, полученный из запроса (вызывает бесконечное перенаправление l oop)
  2. Оставляя метод onAuthenticationSuccess ApiAuthenticationSuccessHandler пустым (возвращает пустую страницу)
  3. Продолжение фильтрация в методе successfulAuthentication фильтра (в конечном итоге вызывает исключение NullPointerException)
  4. Расширение SimpleUrlAuthenticationSuccessHandler и использование setUseReferer(true) в конструкторе (перенаправляет на /)
  5. Использование setDefaultTargetUrl в обработчике при расширении SimpleUrlAuthenticationSuccessHandler и передача URL-адреса из запроса в качестве аргумента (вызывает бесконечное перенаправление l oop)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...