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:

  1. Extract the token from the Authorization header.

  2. 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.

  3. Check Standard Claims

    • exp (expiration): reject if expired.

    • aud (audience): must match “api.myshop.com”.

    • iss (issuer): must be “https://auth.myshop.com”.

  4. Populate Security Context

    • Extract scopes (e.g. orders:read) from the JWT’s scope claim.

    • Map them to Spring authorities (e.g. SCOPE_orders:read).

  5. 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(); }
  • .oauth2ResourceServer().jwt()
    turns on JWT validation.

  • .jwkSetUri(...)
    tells Spring where to fetch your Auth Service’s public keys.


This end-to-end flow—from login to token validation on each request—is the essence of using bearer tokens in real systems.

Comments

Popular Posts