1. JWT and OAuth 2.0 — The Big Picture
A typical enterprise microservices architecture uses an Authorization Server to authenticate users and issue access tokens. The frontend sends the access token to an API Gateway and protected microservices. Spring Security Resource Server validates JWT access tokens and converts their claims into authenticated principals and authorities.
2. Authentication vs Authorization
Authentication
Authentication answers:
Example:
username = srikanth
password = ********
The authentication system verifies that the credentials belong to the user.
Authorization
Authorization answers:
Srikanth
|
├── READ orders ✓
├── CREATE orders ✓
├── DELETE orders ✗
└── ADMIN operations ✗
| Concept | Question | Example |
|---|---|---|
| Authentication | Who are you? | Username/password, SSO, MFA |
| Authorization | What can you do? | ADMIN can delete orders |
3. What is JWT?
JWT = JSON Web Token.
A JWT is a compact token containing claims about a subject. It is digitally signed so that a Resource Server can verify its integrity and origin.
xxxxx.yyyyy.zzzzz
JWT has three parts:
HEADER.PAYLOAD.SIGNATURE
3.1 JWT Header
{
"alg": "RS256",
"typ": "JWT",
"kid": "key-2026-01"
}
| Claim | Meaning |
|---|---|
| alg | Signing algorithm |
| typ | Token type |
| kid | Key identifier used for key selection/rotation |
3.2 JWT Payload
{
"sub": "1001",
"username": "srikanth",
"roles": ["USER"],
"scope": "orders.read orders.write",
"iss": "https://auth.company.com",
"aud": "order-service",
"iat": 1723980000,
"exp": 1723983600
}
These properties are called claims.
| Claim | Meaning |
|---|---|
| sub | Subject, normally user/client identifier |
| iss | Issuer |
| aud | Audience |
| iat | Issued-at time |
| exp | Expiration time |
| nbf | Not valid before |
| scope | OAuth permissions |
| roles | Application-specific roles |
3.3 JWT Signature
For an asymmetric algorithm such as RS256, the Authorization Server signs the header and payload using a private key.
signature =
Sign(
header + "." + payload,
privateKey
)
The Resource Server verifies the signature using the corresponding public key.
3.4 JWT is Not Normally Encrypted
The signature protects integrity and authenticity. It does not provide confidentiality.
4. What is OAuth 2.0?
OAuth 2.0 is an authorization framework. It allows a client to obtain an access token and use that token to access protected resources without directly handling the user's password.
OAuth2 Roles
1. Resource Owner
Usually the user who owns the protected resource.
2. Client
Application requesting access, such as a React application, mobile application or backend service.
3. Authorization Server
Authenticates users and issues access/refresh tokens.
4. Resource Server
API that protects business resources and validates access tokens.
Common Authorization Server / Identity Provider choices include Keycloak, Auth0, Okta, Microsoft Entra ID and Spring Authorization Server.
5. JWT vs OAuth2
| JWT | OAuth 2.0 |
|---|---|
| Token format | Authorization framework |
| Defines token structure | Defines authorization flows and roles |
| Header + Payload + Signature | Client, Authorization Server, Resource Server |
| Can be used independently | Can use JWT as an access token |
| Commonly enables stateless validation | Defines how access is granted |
6. Example Spring Boot Microservices System
Consider an e-commerce application:
| Component | Port | Responsibility |
|---|---|---|
| API Gateway | 8080 | Routing, authentication, rate limiting |
| Authorization Server | 9000 | OAuth2/OIDC, token issuance |
| User Service | 8081 | User APIs |
| Order Service | 8082 | Order APIs |
| Payment Service | 8083 | Payment APIs |
7. Spring Boot Resource Server
Suppose the Order Service is a protected REST API.
Maven Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
application.yml
server:
port: 8082
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://auth.company.com
The issuer-uri tells Spring Security which Authorization Server issued the tokens. Spring Boot/Spring Security can use the issuer metadata to discover the public signing keys and validate JWTs.
SecurityConfig
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(
HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**")
.permitAll()
.requestMatchers(HttpMethod.GET, "/orders/**")
.hasAuthority("SCOPE_orders.read")
.requestMatchers(HttpMethod.POST, "/orders/**")
.hasAuthority("SCOPE_orders.write")
.anyRequest()
.authenticated()
)
.oauth2ResourceServer(
oauth2 -> oauth2.jwt()
);
return http.build();
}
}
Order Controller
@RestController
@RequestMapping("/orders")
public class OrderController {
@GetMapping
public List<String> getOrders() {
return List.of(
"Order-1001",
"Order-1002"
);
}
@PostMapping
public String createOrder() {
return "Order created";
}
}
Calling the API
GET /orders
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Spring Security extracts the Bearer token, validates it and creates an authenticated SecurityContext before the controller is executed.
8. JWT Validation Flow
401 vs 403
| Status | Meaning | Examples |
|---|---|---|
| 401 Unauthorized | Authentication failed | Missing token, invalid signature, expired token |
| 403 Forbidden | Authenticated but not permitted | User lacks required scope/role |
401 = "I don't accept your credentials."
403 = "I know who you are, but you are not allowed."
9. OAuth Scopes
Suppose the JWT contains:
{
"scope": "orders.read orders.write"
}
Spring Security commonly maps OAuth scopes to authorities using the SCOPE_ prefix.
orders.read
↓
SCOPE_orders.read
Therefore this works:
.requestMatchers(HttpMethod.GET, "/orders/**")
.hasAuthority("SCOPE_orders.read")
And:
.requestMatchers(HttpMethod.POST, "/orders/**")
.hasAuthority("SCOPE_orders.write")
10. Roles vs Scopes
| Role | Scope |
|---|---|
| Usually describes the user's application role | Usually describes an allowed access capability |
| ADMIN, USER, MANAGER | orders.read, orders.write |
| Often used for business authorization | Often used for API/resource permissions |
A JWT can contain both:
{
"sub": "1001",
"roles": ["ADMIN"],
"scope": "orders.read orders.write"
}
Custom Role Authority
If your Authorization Server puts roles in a custom claim, configure a JWT authority converter appropriate to that claim.
@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtGrantedAuthoritiesConverter authorities =
new JwtGrantedAuthoritiesConverter();
JwtAuthenticationConverter converter =
new JwtAuthenticationConverter();
converter.setJwtGrantedAuthoritiesConverter(authorities);
return converter;
}
The exact converter configuration depends on whether your provider exposes roles in roles, realm_access.roles, groups or another claim.
11. Accessing the Current User
@GetMapping("/me")
public Map<String, Object> me(
@AuthenticationPrincipal Jwt jwt) {
return jwt.getClaims();
}
Or:
@GetMapping("/me")
public String currentUser(
@AuthenticationPrincipal Jwt jwt) {
return jwt.getSubject();
}
If the token contains:
{
"sub": "1001"
}
then jwt.getSubject() returns 1001.
12. OAuth2 Authorization Code + PKCE
For browser and mobile public clients, Authorization Code with PKCE is a key OAuth2 flow.
Why PKCE?
PKCE protects the authorization-code exchange against interception of the authorization code.
code_verifier
↓ SHA-256
code_challenge
The client initially sends the code_challenge. Later it sends the code_verifier. The Authorization Server verifies that the verifier produces the original challenge.
13. OAuth2 Client Credentials Flow
This is especially important for microservice-to-microservice communication where there is no human user.
Example:
spring:
security:
oauth2:
client:
registration:
payment-service:
provider: company-auth
client-id: order-service
client-secret: ${ORDER_SERVICE_SECRET}
authorization-grant-type: client_credentials
scope:
- payment.read
provider:
company-auth:
token-uri: https://auth.company.com/oauth2/token
Conceptually:
Order Service
|
| client_credentials
▼
Authorization Server
|
| JWT Access Token
▼
Order Service
|
| Bearer JWT
▼
Payment Service
14. Access Token vs Refresh Token
| Token | Purpose | Typical Lifetime |
|---|---|---|
| Access Token | Call protected APIs | Short-lived |
| Refresh Token | Obtain a new access token | Longer-lived |
Example:
Access Token = 15 minutes
Refresh Token = several days (depending on policy)
15. JWT with RSA / Asymmetric Keys
A strong microservices design is to let only the Authorization Server hold the signing private key.
The services only need the public key to verify signatures. They should not possess the private signing key.
16. JWK and JWKS
JWK = JSON Web Key.
JWKS = JSON Web Key Set, a collection of public keys.
Example endpoint:
https://auth.company.com/oauth2/jwks
The JWT header can contain a kid value:
{
"alg": "RS256",
"kid": "key-002"
}
The Resource Server can select the matching public key from the JWKS.
17. Key Rotation
Suppose the current key is:
kid = key-001
Later the Authorization Server introduces:
kid = key-002
JWKS may temporarily contain both:
key-001
key-002
New tokens use key-002, while Resource Servers can continue validating older tokens signed with key-001 until the old key is retired according to the organization's rotation policy.
18. JWT vs Session Authentication
Traditional Session
JWT-Based Access Token
JWT access tokens can enable stateless access-token validation because the Resource Server can validate the token without looking up a server-side HTTP session for every request.
19. API Gateway Authentication vs Microservice Authorization
A common architecture is:
For stronger defense in depth:
The downstream service should not blindly trust security headers supplied by an upstream gateway. It should establish its own security context and perform authorization appropriate to the resource it owns.
20. OAuth2 vs OpenID Connect
OAuth2 primarily addresses authorization.
OpenID Connect (OIDC) adds an identity/authentication layer on top of OAuth2.
OIDC introduces concepts such as:
- ID Token
- UserInfo endpoint
openidscope
Access Token vs ID Token
| Access Token | ID Token |
|---|---|
| Used to authorize API access | Used to communicate authentication/identity information to the client |
| Audience is normally an API/resource server | Audience is normally the client application |
| Used by Resource Server | Used by the Client |
| Contains scopes/authorization information | Contains identity claims |
21. Custom JWT Authentication vs OAuth2
Suppose you implement your own login endpoint and generate a JWT:
@PostMapping("/login")
public TokenResponse login(...) {
// authenticate username/password
String token = Jwts.builder()
.subject(user.getUsername())
.claim("role", user.getRole())
.issuedAt(new Date())
.expiration(expiration)
.signWith(privateKey)
.compact();
return new TokenResponse(token);
}
This is JWT-based authentication.
22. Complete OAuth2 + JWT Microservices Architecture
23. Mapping This to a Typical Spring Boot Microservices Project
A system with an API Gateway, Orchestrator and Auth Service can evolve into the following design:
With OAuth2/OIDC, the Auth Service can be replaced or supplemented by a dedicated Authorization Server/Identity Provider. The application services can become OAuth2 Resource Servers.
24. Should You Build Your Own Authorization Server?
For enterprise systems, avoid implementing OAuth2 security protocols from scratch unless there is a strong architectural reason.
Common established choices include:
If you need to operate your own Authorization Server, Spring Authorization Server is one option. Note that current Spring Authorization Server releases have their own Java/Spring version requirements, so verify compatibility before selecting it for a Java 11 application.
25. Production Security Checklist
Token Security
- Short-lived access tokens
- Strong signing algorithms
- Validate signature
- Validate issuer
- Validate audience
- Validate expiration
- Validate not-before where applicable
Authorization
- Use least privilege
- Use scopes
- Use roles where appropriate
- Perform resource-level authorization
- Do not rely only on gateway authorization
Infrastructure
- HTTPS everywhere
- Secure private-key storage
- Key rotation
- JWKS
- Vault / Secret Manager
- Audit security events
Refresh Tokens
- Secure storage
- Rotation
- Revocation
- Shorten lifetime when appropriate
- Do not expose unnecessarily
Microservices
- Validate JWT at Resource Server
- Do not blindly trust gateway headers
- Use Client Credentials for service-to-service calls where appropriate
- Use separate scopes/audiences for services
26. Complete Mental Model
| Term | Meaning |
|---|---|
| JWT | How a token is represented |
| OAuth2 | Framework for delegated authorization |
| OIDC | Identity/authentication layer on OAuth2 |
| Authorization Server | Issues access/refresh tokens |
| Resource Server | Protects APIs and validates access tokens |
| OAuth2 Client | Requests/uses tokens |
| Access Token | Used to access protected APIs |
| Refresh Token | Used to obtain new access tokens |
| Scope | Permission/capability represented in OAuth2 |
| Role | Application-level authority such as ADMIN or USER |
| JWK/JWKS | JSON representation/set of cryptographic keys |
27. Interview-Ready Answer
Question: Explain JWT and OAuth2 in a microservices architecture.
JWT is a token format containing claims that are digitally signed, while OAuth2 is an authorization framework defining how clients obtain and use access tokens. In a typical Spring Boot microservices architecture, an Authorization Server authenticates the user and issues a short-lived JWT access token. The client sends it as a Bearer token through the API Gateway to protected services. The Gateway and/or downstream Resource Servers validate the JWT signature using the Authorization Server's public key or JWKS and validate claims such as issuer, audience and expiration. Spring Security converts scopes or roles into authorities and performs authorization at the endpoint level. For service-to-service communication where there is no user, OAuth2 Client Credentials is commonly used. For browser-based authorization, Authorization Code with PKCE is commonly used.
The key distinction
OAuth2
↓
How authorization/access is granted
JWT
↓
How the access token can be represented
Spring Security Resource Server
↓
How the API validates the token
Scopes / Roles
↓
How API authorization decisions are made
28. Quick Revision Cheat Sheet
| Question | Answer |
|---|---|
| What is JWT? | Signed token format containing claims. |
| Is JWT encrypted? | Normally no. It is encoded and signed. |
| What is OAuth2? | Authorization framework. |
| Does OAuth2 require JWT? | No. OAuth2 can use opaque tokens too. |
| Who issues access tokens? | Authorization Server. |
| Who validates access tokens? | Resource Server, often with Spring Security. |
| What is a scope? | Permission/capability. |
| What is a role? | Application/business authority. |
| What is 401? | Authentication failed or credentials are missing/invalid. |
| What is 403? | Authenticated but not authorized. |
| What is PKCE? | Protection for authorization-code flow against code interception. |
| What is Client Credentials? | OAuth2 flow commonly used for service-to-service access. |
| What is OIDC? | Identity layer built on OAuth2. |
| What is JWKS? | Set of JSON Web Keys used to publish verification keys. |
| Why RS256? | Private key signs; public key verifies, making distribution to services safer. |