Cách tích hợp Spring Security với Spring Cloud Gateway
Dưới đây là hướng dẫn chi tiết cách tích hợp Spring Security với Spring Cloud Gateway, giúp bạn kiểm soát xác thực (authentication) và phân quyền (authorization) ngay tại lớp Gateway – rất quan trọng để bảo vệ toàn bộ hệ thống microservices.
🎯 Mục tiêu:#
Xác thực request bằng JWT (JSON Web Token)
Áp dụng bảo mật ở Gateway, không cần lặp lại trong từng service
Từ chối truy cập nếu token không hợp lệ
🧱 Cấu trúc hệ thống mẫu#
Client | v Spring Cloud Gateway (Spring Security) | +--> User Service +--> Product Service
1. Thêm dependency vào pom.xml#
`
2. Cấu hình bảo mật với WebFlux#
` @Configuration @EnableWebFluxSecurity public class SecurityConfig {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
return http
.csrf().disable()
.authorizeExchange(exchanges -> exchanges
.pathMatchers("/auth/**").permitAll()
.anyExchange().authenticated()
)
.addFilterAt(new JwtAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
.build();
}
} `
3. Tạo JWT Authentication Filter#
` public class JwtAuthenticationFilter implements WebFilter {
private final String SECRET_KEY = "my-secret";
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String authHeader = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = authHeader.substring(7);
try {
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
String username = claims.getSubject();
if (username != null) {
Authentication auth = new UsernamePasswordAuthenticationToken(
username, null, List.of(new SimpleGrantedAuthority("ROLE_USER"))
);
return chain.filter(exchange)
.contextWrite(ReactiveSecurityContextHolder.withAuthentication(auth));
}
} catch (Exception e) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
}
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
} `
4. Test với route cấu hình trong application.yml#
spring: cloud: gateway: routes: - id: product-service uri: http://localhost:8081 predicates: - Path=/api/products/**
- Gửi request tới
/api/products/**phải có header:
Authorization: Bearer <jwt-token>
🔒 Ưu điểm của việc tích hợp Spring Security tại Gateway:#
✅ Giảm gánh nặng bảo mật cho từng service ✅ Tập trung kiểm soát bảo mật một chỗ ✅ Hỗ trợ mở rộng các cơ chế như: Role-based access, Rate limiting, IP whitelist, OAuth2, ...