Skip to main content

πŸ‘‰ Unlocking JWT Security: A Deep Dive into Token Validation in Spring Boot

Hi πŸ‘‹, I’m Anandharaj.


Today’s Learnings : JWT Token Validation in Spring Security

πŸ”Ή Always Spring Security gives confusion to me.
So I’m sharing my learnings on how a JWT token is validated when a request comes in.



🌍 What happens when a request comes in?

1️⃣ Incoming request with a token
When a request hits your API, Spring Security’s filter chain intercepts it and extracts the token from the Authorization header (usually in the format: Bearer <token>).

2️⃣ Check token type
The filter checks if it’s a Bearer token and then hands it over to a configured JWT decoder.


πŸ”Ž JWT Structure

A JWT has three parts, separated by dots (.):

  • Header πŸ‘‰ contains metadata (e.g., algorithm: HS256, RS256)

  • Payload πŸ‘‰ contains claims (user info, expiry time, issuer, audience, etc.)

  • Signature πŸ‘‰ ensures integrity and authenticity

πŸ‘‰ Header and Payload are Base64URL‑encoded and readable.
πŸ‘‰ Signature is cryptographically generated and cannot be reverse‑engineered.




πŸ›  How Spring validates a JWT

✔️ Step 1: Decoder setup
When your Spring Boot app starts, it uses a configured JwtDecoder.

For example:


.oauth2ResourceServer(oauth2 -> { oauth2.jwt(jwt -> { jwt.decoder(jwtDecoder); }); });
  • The JwtDecoder is initialized with trusted details (like public keys or JWK Set URIs) from your identity provider.

  • These details are usually cached by Spring for performance.


✔️ Step 2: Validation process

When a token arrives:

  • Header & Payload validation:
    The decoder checks claims like exp (expiry), iss (issuer), aud (audience) against the trusted configuration.

  • Signature validation:
    Using the public key (fetched from the trusted issuer during app startup), Spring recalculates the signature from the header and payload and compares it with the signature part of the token.

✅ If everything matches, the token is valid.


❌ If not, access is denied.



πŸ’‘ Key Takeaways

✅ Always configure a JwtDecoder that matches the way your tokens are generated (e.g., RS256 → use a JWK set URI from your identity provider).


✅ Remember the three parts of a JWT – only header and payload are human-readable; the signature is cryptographically protected.


✅ Spring Security handles this flow through its filter chain and caching, so you rarely need to manually decode tokens.



πŸ–₯ Bonus Tip

If you want to inspect a token manually, try https://jwt.io.
Paste your token, and you’ll see the header, payload, and whether the signature is verified (see my screenshot above).


✍️ This was a quick note from my daily learnings.


If you’ve struggled with JWT validation, hope this helps you understand the flow better! πŸš€


Comments

Popular posts from this blog

🐱 Tomcat vs ⚡ Netty – Which One Should You Use?

🐱 Tomcat vs ⚡ Netty – Which One Should You Use? So recently I got curious about this too πŸ€”. Everywhere in Spring Boot tutorials we see Tomcat . Then suddenly while exploring Spring WebFlux , the name Netty pops up. And I was like – “Wait, who’s this Netty guy trying to replace Tomcat?” πŸ˜… Let’s break it down with real-time examples , icons , and fun comparisons . 🐱 Tomcat – The Traditional Web Server Type: Servlet Container (blocking I/O) World: Used with Spring MVC Style: Thread-per-request model πŸ‘©‍πŸ’» Pros: Stable, widely used, battle-tested Cons: Struggles with huge concurrent connections πŸ‘‰ Example in real life: Tomcat is like a restaurant with fixed waiters 🍴. - Each customer = one thread/waiter - If too many customers come in at once → waiters run out → customers wait outside πŸšͺ ⚡ Netty – The Reactive Rockstar Type: Asynchronous Event-Driven Network Framework World: Default for Spring WebFlux Style: Event-lo...

🎭 Spring’s Secret: Why @Transactional & Friends Betray You Silently

πŸ’‘ Lesson Learned — Not a Prod Bug, But a Real Pain No, this wasn’t a production outage. Nobody screamed at me. But I sat for 3 hours wondering: “Why the heck is my @Transactional not rolling back!?” 😡‍πŸ’« “Why is Redis cache not working?” 🀯 Turned out, the issue was one silent villain: 🧱 Self-invocation 🀷 What Is @Transactional ? If you're new: @Transactional = Tells Spring to start a DB transaction when a method is called. It’ll commit if everything’s okay. It’ll rollback if something fails. 🧠 Think of it like wrapping your code in: try { beginTransaction(); // your logic commit(); } catch(Exception e) { rollback(); } πŸ•΅️ Real-Life Analogy — The Gateway Community 🏘️ Let me tell you about my society — it has a strict watchman at the gate. Here’s how it works: πŸ›‚ Watchman = Spring Proxy 🏠 Your apartment = Your service class πŸšͺ Your room = A method inside that class πŸƒ Scenario 1: Outsider Visits Your friend from outside...

🌟 My Journey – From Zero to Senior Java Tech Lead 🌟

 There’s one thing I truly believe… If I can become a Java developer, then anyone in the world can. πŸ’― Sounds crazy? Let me take you back. πŸ•“ Back in 2015… I had zero coding knowledge . Not just that — I had no interest in coding either. But life has its own plans. In 2016, I got a chance to move to Bangalore and joined a Java course at a training center. That’s where it all started — Every day, every session made me feel like: "Ohhh! Even I can be a developer!" That course didn’t just teach Java — it gave me confidence . πŸ§ͺ Two Life-Changing Incidents 1️⃣ The Interview That Wasn't Planned Halfway through my course, I had to urgently travel to Chennai to donate blood to a family member. After that emotional rollercoaster, I found myself reflecting on my skills and the future. The next day, as I was preparing for my move to Bangalore to complete the remaining four months of my course, I randomly thought — "Let me test my skills... let me just see...