Spring Boot
JWT Authentication Flow
Understand how JWT (JSON Web Tokens) authentication works in Spring Boot, how bearer tokens are validated, and how claims become authorities.
The Short Version
Typical JWT Flow
- User logs in through an identity provider (Okta, Auth0, Microsoft Entra ID, Keycloak, Google) or auth endpoint.
- The server returns a signed JWT token.
- The client stores the token and sends it on later requests.
- The token is sent in the
Authorizationheader. - Spring Security validates the token signature and claims.
- If valid, Spring creates an authenticated security context.
- Authorization rules decide whether the user can access the API.
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...Spring Boot Resource Server Setup
In many production systems, the Spring Boot API is not the identity provider. Instead, it acts as a resource server (OAuth2 Resource Server dependency). That means it accepts JWTs issued by another trusted service.
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/token").permitAll()
.requestMatchers("/api/products/**").hasAuthority("SCOPE_products:read")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(jwt -> {})
)
.build();
}What Is Inside a JWT?
A JWT usually contains claims. Claims are pieces of information about the authenticated user or client.
{
"sub": "user-123",
"scope": "products:read products:write",
"iss": "https://auth.example.com",
"aud": "inventory-api",
"exp": 1735689600
}sub: the subject, usually the user or client id.scope: permissions granted to the token.iss: issuer of the token.aud: intended audience of the token.exp: expiration time.
How Scopes Become Authorities
Spring Security commonly maps JWT scopes into authorities with the prefix SCOPE_.
scope: "products:read products:write"
// becomes:
SCOPE_products:read
SCOPE_products:writeThat is why this authorization rule checks for SCOPE_products:read:
.requestMatchers("/api/products/**")
.hasAuthority("SCOPE_products:read")Access Tokens vs Refresh Tokens
In many JWT authentication systems, the client actually receives two different tokens:
- Access Token — short-lived token used for API requests.
- Refresh Token — longer-lived token used to obtain new access tokens after expiration.
The access token is commonly a JWT containing claims about the user and permissions.
{
"sub": "user-123",
"scope": "products:read products:write",
"iss": "https://auth.example.com",
"aud": "inventory-api",
"exp": 1735689600
}The refresh token is usually a separate token returned alongside the access token.
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "def50200ab8c9f1d7e5..."
}When the access token expires, the client sends the refresh token to the authorization server to obtain a new access token.
Access Token
Short-lived, sent to APIs, usually contains claims and scopes.
Refresh Token
Longer-lived, used only with the auth server to obtain new access tokens.
What Interviewers Are Looking For
Authentication vs Authorization
Authentication verifies who the caller is. Authorization decides what they are allowed to access.
Stateless Requests
With JWTs, the server usually does not need a session for every logged-in user.
Token Validation
The API must validate signature, expiration, issuer, audience, and required claims.
Scopes and Roles
JWT claims often become Spring Security authorities used in access rules.
Resource Server Role
The API often validates tokens but does not issue them itself.
Security Tradeoffs
JWTs are convenient, but revocation, expiration, refresh tokens, and token storage need careful design.
Common Follow-Ups
Is JWT authentication stateful or stateless?
Usually stateless. The server validates the token on each request instead of storing session state for every user.
Where should the JWT be sent?
Usually in the Authorization header as a Bearer token.
Does the API need to call the auth server on every request?
Not usually. If the API can validate the token signature using a trusted key, it can validate the JWT locally.
What happens when a JWT expires?
The request should be rejected. The client usually needs to obtain a new access token, often using a refresh token flow.
What is the risk with long-lived JWTs?
If stolen, a long-lived JWT may remain usable until it expires. Short expiration times reduce that risk.