service-to-service — token relay, client credentials, exchange and mTLS
Companion project for
Securing Spring Boot Microservices: Token Relay, Service-to-Service JWT and mTLS
on ankurm.com.
Four real processes and a real Spring Authorization Server, so that questions like "whose
identity arrives at the last service?" and "what does that service actually check?" have
transcripts for answers. Everything under docs/output/ was produced by
scripts/run-all.sh.
Versions
|
Version |
Notes |
| JDK |
25 (Temurin 25.0.4.1+1) |
current LTS |
| Spring Boot |
4.1.1 |
inherited as parent |
| Spring Framework |
7.0.9 |
|
| Spring Security |
7.1.1 |
resource server, OAuth2 client, authorization server |
| Spring Cloud |
2025.1.3 (gateway 5.0.3) |
built against Boot 4.0.8 — see docs/01 |
| Tomcat |
11.0.24 |
|
Versions were read from repo1.maven.org/.../maven-metadata.xml.
Quickstart
The user is alice / password.
Processes
Endpoints
| Endpoint |
Strategy |
GET /edge/naive |
No token forwarded — the control |
GET /edge/relay |
The incoming bearer token, unchanged |
GET /edge/client-credentials |
The edge service's own identity |
GET /edge/exchange |
RFC 8693 token exchange |
GET /edge/relay-async |
Relay from another thread — the ThreadLocal trap |
GET /orders |
Downstream. Echoes sub, aud, scope, client_id, cnf |
GET /mtls/whoami |
The verified certificate identity |
GET /mtls/trusted-header |
An identity taken from a header, verified by nothing |
Switches
| Switch |
Effect |
STRICT=true ./scripts/run.sh |
Authorization server emits RFC 9068 tokens; downstream validates issuer, audience and the required-claim set |
RS_LOG_LEVEL / CLIENT_LOG_LEVEL / AS_LOG_LEVEL / GATEWAY_LOG_LEVEL |
DEBUG on the corresponding package |
Documentation
| Chapter |
|
| 01 |
The four processes, a browser flow in curl, and four things that cost time |
| 02 |
Relay, client credentials, token exchange — and the thread that loses the token |
| 03 |
OAuth2ClientHttpRequestInterceptor and which OAuth2AuthorizedClientManager |
| 04 |
What a resource server does not validate by default |
| 05 |
What TokenRelay actually relays |
| 06 |
Mesh mTLS versus in-application mTLS |
| 07 |
Choosing, and whether you need any of it |
Captured output
Related modules