Чтение токена JWT в службе REST с использованием AbstractPreAuthenticatedProcessingFilter

Следующий сценарий: моя служба REST Spring Boot 2.0 получает запросы, сделанные клиентом Angular 6 через шлюз API, который общается с Keycloak. Таким образом, запрос выполняется уже аутентифицированным пользователем (выполняется API Gateway). Информация о пользователе и его ролях упакована в токен JWT, который является частью запроса (в заголовке авторизации с токеном носителя).

Как обработать токен на стороне сервиса?

Я строю TokenPreAuthenticatedProcessingFilter (на основе AbstractPreAuthenticatedProcessingFilter) настроил это по моему WebSecurityConfigurerAdapter следующее:

    protected void configure(HttpSecurity http) throws Exception {
    http.antMatcher("/**")
            .cors()
            .and()
            .authorizeRequests()
            .mvcMatchers(HttpMethod.GET, "/health", "/info").anonymous()
            .anyRequest().authenticated()
            .and()
            .addFilterBefore(tokenPreAuthenticatedFilter(), RequestHeaderAuthenticationFilter.class)
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.NEVER)
            .and()
            .csrf().disable();

Пока все хорошо, однако после достижения (и выполнения) конечной точки в контроллере запрос перенаправляется, и клиент получает код состояния HTTP 302 в качестве ответа вместо данных.

Вопросы:

  1. Является ли подход с AbstractPreAuthenticatedProcessingFilter по этому сценарию правильно? (Я прочитал в документации http://springcert.sourceforge.net/sec-3/preauth.html и это должно быть),
  2. Если да, то как избежать перенаправления?
  3. Если нет, то как это сделать другим и правильным способом?

1 ответ

Похоже, вы настроили свой WebSecurityConfigurerAdapter как процессор типа MVC, поэтому вы получаете 302, а не 200 и данные. Для этого вам не нужны cors, поэтому отключите его, вы должны использовать ant matchers для путей, а не mvc matchers. Я не уверен в политике создания сеанса, но я обычно устанавливаю это как не сохраняющее состояния. и я бы установил форму входа в систему отключенным. Таким образом, полученная конфигурация будет выглядеть примерно так:

http.cors().and().csrf().disable().authorizeRequests()
        .anyRequest().authenticated()
        .antMatchers(HttpMethod.GET, "/health", "/info").anonymous()
        .and()
        .addFilterBefore(tokenPreAuthenticatedFilter(), RequestHeaderAuthenticationFilter.class)
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and().formLogin().disable();

У меня нет остальной части вашего кода, поэтому я не могу протестировать эту конфигурацию, но, я надеюсь, она может продвинуть вас далеко по правильному пути.

Другие вопросы по тегам