Securing a single REST API is a good start—but in real-world enterprise environments, you’re likely dealing with multiple microservices, user roles, and external clients. The ideal way to manage all this is with an Identity Provider like Keycloak and an API Gateway such as Spring Cloud Gateway or Kong Gateway.

In this article, we’ll go a step further and:

  • Set up Keycloak for identity and access management

  • Secure Spring Boot microservices using Keycloak + OAuth2

  • Use API Gateway to enforce SSL, route requests, and validate tokens centrally

By the end, you’ll have a production-grade security architecture for your Spring Boot apps.

Architecture Overview

Here’s how the components interact:

csharp
[User or Client]


[API Gateway (SSL Termination, JWT Validation)]


[Spring Boot Microservices]


[Keycloak (Authentication + Authorization Server)]
  • The client authenticates with Keycloak

  • Gets a JWT Access Token

  • Sends requests to API Gateway

  • Gateway validates token, routes to the correct Spring Boot service

  • Microservice trusts the gateway and verifies any additional roles/scopes

Set Up Keycloak Identity Provider

You can run Keycloak using Docker:

bash
docker run -d \
--name keycloak \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-p 8081:8080 \
quay.io/keycloak/keycloak:24.0 \
start-dev

Access Keycloak UI at http://localhost:8081

Create Realm, Client, and Users

  1. Create Realm: e.g., spring-boot-realm

  2. Create Client: e.g., spring-api-client

    • Access Type: confidential

    • Valid redirect URIs: * (for testing)

    • Enable: Authorization, Standard Flow, Direct Access Grants

  3. Create Roles: USER, ADMIN

  4. Create Users: Assign roles and credentials

Secure Spring Boot Microservice with Keycloak

Dependencies (pom.xml):

xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>

application.properties:

properties
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8081/realms/spring-boot-realm

Security config:

java
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers(“/api/admin/**”).hasRole(“ADMIN”)
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2
.jwt()
);
return http.build();
}
}

Now, Spring Boot validates JWTs issued by Keycloak.

Test Keycloak Authentication and Tokens

Obtain a token with curl:

bash
curl -X POST http://localhost:8081/realms/spring-boot-realm/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password&client_id=spring-api-client&username=testuser&password=password"

Use the access_token to hit the Spring Boot API:

bash
curl -H "Authorization: Bearer <access_token>" https://localhost:8443/api/hello

Use Spring Cloud Gateway to Validate Tokens and Route

Create a new Spring Boot app for the gateway.

Dependencies (Spring Cloud Gateway):

xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

application.yml:

yaml
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8081/realms/spring-boot-realm
cloud:
gateway:
routes:
id: user-service
uri: http://localhost:8082
predicates:
Path=/api/user/**
filters:
StripPrefix=1

Enable security filter:

java
@Configuration
public class GatewaySecurityConfig {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange(ex -> ex
.pathMatchers(“/api/user/**”).hasRole(“USER”)
.anyExchange().authenticated()
)
.oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::jwt);
return http.build();
}
}

This configuration ensures:

  • Gateway validates the token

  • Rejects unauthorized users before forwarding to backend

  • Backend only deals with valid, pre-authenticated requests

SSL Termination at the Gateway (Optional)

You can terminate SSL at the gateway level using Spring Boot or put NGINX in front of it (as discussed earlier).

If Spring Gateway handles SSL:

properties
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:gateway-keystore.p12
server.ssl.key-store-password=changeit

Now you’ve centralized:

  • Authentication

  • Routing

  • Token validation

  • SSL

in the API gateway.

Conclusion

Securing modern microservices goes beyond encrypting traffic with SSL—it requires authentication, authorization, and centralized management. With this architecture, we’ve combined several powerful technologies:

  • Keycloak for federated identity and OAuth2 token issuance

  • Spring Boot for REST microservices secured by JWT

  • Spring Cloud Gateway for API routing, HTTPS, and centralized token validation

This setup offers multiple advantages:

✅ Centralized token validation and routing
✅ Fine-grained role-based access in microservices
✅ SSL termination handled securely in one place
✅ Scalable and modular—easy to plug in rate limiting, CORS, and logging
✅ Dev/prod ready—swap Keycloak with any OAuth2 provider (Auth0, Okta, etc.)

This architecture lays the foundation for secure, cloud-native applications that are resilient, modular, and compliant with modern standards. You can further extend it by:

  • Adding refresh token support in frontend apps

  • Enabling audit logging and request tracing

  • Integrating with Kubernetes Ingress for autoscaling

  • Using Let’s Encrypt for automated SSL certificate renewal

By following these practices, you lay the foundation for secure communication, reduce the risk of data breaches, and instill confidence in your API consumers. Security is never optional, and integrating SSL with Spring Boot is an investment in the long-term integrity and credibility of your applications.