Bearer Token
Let’s walk through a concrete scenario step by step—an e-commerce app where a mobile client talks to two services: an Auth Service (issues tokens) and an Order Service (protects endpoints).
1. User Logs In and Gets a Bearer Token
Request to Auth Service
POST https://auth.myshop.com/login Content-Type: application/json { "username": "alice@example.com", "password": "P@ssw0rd!" }
Response from Auth Service
HTTP/1.1 200 OK Content-Type: application/json { "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." "token_type": "Bearer", "expires_in": 3600, "scope": "orders:read orders:write" }
-
access_token
is a JWT (JSON Web Token). -
The client stores it (e.g. in memory or secure storage).
2. Client Calls a Protected Endpoint
Alice’s app now wants to fetch her orders:
GET https://api.myshop.com/orders
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
-
Note the header:
Authorization: Bearer <token>
.
3. Order Service Validates the Token
Under the hood, Spring Security’s Resource Server filter chain does this automatically:
-
Extract the token from the
Authorization
header. -
Decode & Verify Signature
-
Fetch the public keys from the Auth Service’s JWK endpoint (e.g.
https://auth.myshop.com/.well-known/jwks.json
). -
Use them to verify the JWT’s cryptographic signature—ensures it really came from your Auth Service.
-
-
Check Standard Claims
-
exp
(expiration): reject if expired. -
aud
(audience): must match “api.myshop.com”. -
iss
(issuer): must be “https://auth.myshop.com”.
-
-
Populate Security Context
-
Extract scopes (e.g.
orders:read
) from the JWT’sscope
claim. -
Map them to Spring authorities (e.g.
SCOPE_orders:read
).
-
-
Authorize the Request
-
Your
HttpSecurity
config says.antMatchers("/orders").hasAuthority("SCOPE_orders:read")
. -
If Alice’s token has that scope, the call proceeds. Otherwise, she gets 403 Forbidden.
-
4. Order Service Responds
HTTP/1.1 200 OK Content-Type: application/json [ { "orderId": 123, "total": 49.95, … }, { "orderId": 124, "total": 19.99, … } ]
Alice sees her order list. All without ever sending username/password again—just the bearer token.
Key Points
-
Bearer means “anyone holding this token can use it.” Keep it secret!
-
JWTs are self-contained: you don’t need a database lookup on each request (just key lookup).
-
Validation = signature check + claim checks (+ optional revocation or introspection).
-
Spring Security’s resource-server support wires all this up with just a few lines of config.
Spring Security Config Snippet
@Bean SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/orders").hasAuthority("SCOPE_orders:read") .anyRequest().authenticated() ) .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt .jwkSetUri("https://auth.myshop.com/.well-known/jwks.json") ) ); return http.build(); }
-
turns on JWT validation.
.oauth2ResourceServer().jwt()
-
tells Spring where to fetch your Auth Service’s public keys.
.jwkSetUri(...)
This end-to-end flow—from login to token validation on each request—is the essence of using bearer tokens in real systems.
Comments
Post a Comment