JWT decoding with Spring Security
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Spring Security provides built-in support for decoding and validating JSON Web Tokens (JWTs) through its OAuth2 Resource Server module. A JWT consists of three Base64URL-encoded parts — header, payload, and signature — separated by dots. Spring Security's JwtDecoder validates the signature, checks claims like expiration and issuer, and converts the token into an Authentication object. Configuration requires adding the spring-boot-starter-oauth2-resource-server dependency and setting the issuer URI or JWK Set endpoint.
JWT Structure
Spring Boot Configuration
Add the dependency:
Configure the issuer URI in application.yml:
Spring Boot auto-configures a JwtDecoder that fetches the public keys from the issuer's JWKS endpoint.
Security Configuration
Custom JwtDecoder Bean
For scenarios where you need a custom decoder (symmetric keys, custom validation):
Adding Custom Claim Validation
Accessing JWT Claims in Controllers
Manual JWT Decoding (Without Spring Security)
For decoding without the full security framework:
This does NOT verify the signature. Only use for debugging or when the signature is verified elsewhere.
Common Pitfalls
- Not validating the signature: Decoding the payload with Base64 is trivial — anyone can read JWT claims. The signature validation is what proves the token is authentic and untampered. Always use
JwtDecoderwith proper key configuration. - Wrong issuer or audience claim: If the
issoraudclaim in the token does not match your validation config, Spring Security rejects the token with a generic 401. Check both the token and the config for exact string matches. - Clock skew causing expiration failures: Tokens that expire right at the boundary may fail due to clock differences between the auth server and your application. Configure clock skew tolerance with
JwtTimestampValidator(Duration.ofSeconds(60)). - Confusing scope authorities prefix: Spring Security prefixes JWT scopes with
SCOPE_by default. A JWT with"scope": "read write"maps to authoritiesSCOPE_readandSCOPE_write, notreadandwrite. UsehasAuthority("SCOPE_read")or customize the prefix. - JWKS endpoint caching:
NimbusJwtDecodercaches the JWK Set. If the auth server rotates keys, existing tokens may fail until the cache refreshes. Configure cache TTL or implement aJWKSetCachewith appropriate expiration.
Summary
- Add
spring-boot-starter-oauth2-resource-serverand setissuer-urifor automatic JWT decoding - Use
JwtAuthenticationConverterto map JWT claims to Spring Security authorities - Access JWT claims in controllers with
@AuthenticationPrincipal Jwt jwt - Add custom validators for audience, issuer, or domain-specific claims
- Never decode JWTs by Base64 alone in production — always validate the signature
Related reading
- JWT 'module' object has no attribute 'encode
- Kafka-topics --list using ssl
- Kafka-topics.sh authentication
- kafka - ssl handshake failing
- jython multithreading
- Kafka - Could not find a 'KafkaClient' entry in the JAAS configuration java
- Kafka 10 - Python Client with Authentication and Authorization
- Kafka and firewall rules

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.