Я создаю шлюз для микросервисов Spring Boot, используя Spring Cloud Gateway. Шлюз также отвечает за авторизацию JWT с использованием Spring Security.
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
...
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String header = request.getHeader(JwtProperties.HEADER_STRING);
if (header == null || !header.startsWith(JwtProperties.TOKEN_PREFIX)) {
chain.doFilter(request, response);
return;
}
Authentication authentication = getUsernamePasswordAuthentication(request);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(request, response);
}
private Authentication getUsernamePasswordAuthentication(HttpServletRequest request) {
String token = request.getHeader(JwtProperties.HEADER_STRING).replace(JwtProperties.TOKEN_PREFIX, "");
DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC512(JwtProperties.SECRET.getBytes())).build().verify(token);
String username = decodedJWT.getSubject();
if (username != null) {
UserPrincipal principal = (UserPrincipal) userPrincipalService.loadUserByUsername(username);
Authentication auth = new UsernamePasswordAuthenticationToken(username, null, principal.getAuthorities());
return auth;
}
return null;
}
}
Этот фильтр регистрируется в методе configure следующим образом:
@Configuration
@EnableWebSecurity
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
...
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilter(new JwtAuthorizationFilter(authenticationManager(), userPrincipalService))
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/login").permitAll()
...
.anyRequest().authenticated();
}
...
}
Как видите, Spring Security использует интерфейсы HttpServletRequest, HttpServletResponse, FilterChain, принадлежащие spring-boot-starter-web. Но это главная проблема, потому что она несовместима с Spring Cloud Gateway.
Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway at this time. Please remove spring-boot-starter-web dependency.
Есть ли способ избежать этой ошибки или любого другого решения для реализации фильтра авторизации jwt на шлюзе? Спасибо!




В Документации весеннего облачного шлюза прямо указано, что этот продукт работает поверх Netty и требует webflux, поэтому он не совместим с Spring MVC.
Используемый вами фильтр (JwtAuthorizationFilter) относится к нереактивному миру, поэтому вам, вероятно, следует переписать его с помощью Spring Security для строительных блоков web flux.
Отказ от ответственности, я не являюсь экспертом по Spring Web Flux / spring-security, но, пожалуйста, рассмотрите возможность проверки Это приложение - оно показывает, как определить защищенное приложение JWT с реактивной версией безопасности Spring.
Таким образом, вы должны выбрать, хотите ли вы реактивное приложение или традиционное, и использовать соответствующие технологии, но вы не можете их смешивать.