Чтение токена 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 в качестве ответа вместо данных.
Вопросы:
- Является ли подход с
AbstractPreAuthenticatedProcessingFilter
по этому сценарию правильно? (Я прочитал в документации http://springcert.sourceforge.net/sec-3/preauth.html и это должно быть), - Если да, то как избежать перенаправления?
- Если нет, то как это сделать другим и правильным способом?
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();
У меня нет остальной части вашего кода, поэтому я не могу протестировать эту конфигурацию, но, я надеюсь, она может продвинуть вас далеко по правильному пути.