What is Spring Cloud Zuul?
Zuul is Netflix's edge service gateway, now maintained by the Spring Cloud community. It routes incoming HTTP requests to backend services, providing dynamic routing, monitoring, resiliency, and security. In a micro‑service architecture, Zuul often sits at the perimeter, making it a prime target for attacks. Securing it with Spring Security ensures that only authenticated and authorized traffic reaches your services.
More from this site
Keep reading the latest coverage
Why Secure Zuul?
Without protection, Zuul can expose internal services, allow brute‑force attacks, and become a conduit for path‑traversal or header‑based attacks. Spring Security offers OAuth2, JWT, basic auth, and custom filters, giving you granular control over who can access what.
Prerequisites
To follow this guide you'll need:
- Java 17 or later
- Spring Boot 3.x
- Spring Cloud 2023.x (or newer)
- Gradle or Maven
- Postman or curl for testing
Project Setup
Build file (Gradle)
```groovy plugins { id 'org.springframework.boot' version '3.2.5' id 'io.spring.dependency-management' version '1.1.5' id 'java' }
group = 'com.example' version = '0.0.1-SNAPSHOT'
repositories { mavenCentral() }
dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.cloud:spring-cloud-starter-gateway' implementation 'org.springframework.cloud:spring-cloud-starter-oauth2-client' testImplementation 'org.springframework.boot:spring-boot-starter-test' }
dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:2023.0.0" } }
spring.application.name=zuul-gateway
server.port=8080
# JWT configuration
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://your‑auth‑server/.well‑known/jwks.json
# Example route
spring.cloud.gateway.routes[0].id=example-service
spring.cloud.gateway.routes[0].uri=http://localhost:8081
spring.cloud.gateway.routes[0].predicates[0]=Path=/api/**
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/actuator/**").permitAll() .anyRequest().authenticated() ) .httpBasic(); return http.build(); } }
@Configuration
public class JwtConfig {
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withJwkSetUri("https://your‑auth‑server/.well‑known/jwks.json").build();
}
}
@Component public class HeaderFilter extends AbstractGatewayFilterFactory { @Override public GatewayFilter apply(Object config) { return (exchange, chain) -> { if (!exchange.getRequest().getHeaders().containsKey("X-API-Key")) { return Mono.error(new ResponseStatusException(HttpStatus.FORBIDDEN, "Missing X-API-Key")); } return chain.filter(exchange); }; } }
curl -i -H "Authorization: Bearer " http://localhost:8080/api/hello