Skip to main content

Command Palette

Search for a command to run...

Securing APIs with Spring Security & JWT

A JWT moves the session into the token itself — which buys you scale and hands you a new set of ways to get it wrong.

Updated
4 min readView as Markdown
Securing APIs with Spring Security & JWT
I
Welcome to Bits8Byte! I’m Ish, an AI Engineer with 13+ years of experience across software engineering, automation, cloud, and AI-driven systems. This blog is where I share practical insights, technical deep dives, and real-world lessons from building modern software and exploring the fast-moving world of AI. My background spans Java, Spring Boot, Python, FastAPI, AWS, Docker, Kubernetes, DevOps, observability, and automation. Today, my work is increasingly focused on AI engineering, including LLM applications, AI agents, production-grade microservices, and scalable cloud-native architectures. Here, you’ll find thoughtful writing on AI trends, engineering best practices, software architecture, and the mindset required to adapt and grow in the age of AI. My aim is not just to explain technology, but to make it useful, practical, and grounded in real implementation experience. Thanks for stopping by. I hope this space helps you learn something valuable, think more deeply, and stay ahead in a rapidly evolving industry.

Traditional web login keeps a session on the server. You log in, the server remembers you, and your browser carries a session cookie that points back to that memory. It works fine for one server talking to a browser. It fits an API badly. APIs get called by many kinds of client and scaled across many server instances, and a server-side session means every one of those instances has to share or look up that state. JWT authentication exists, more or less, to let the server forget.

What a JWT actually is

A JSON Web Token is a self-contained, signed statement of who you are. When you log in, the server hands you a token that encodes your identity and a few claims, signed with a secret only the server knows. On every request after that you send the token back — in the Authorization header, prefixed with "Bearer" — and the server verifies the signature before trusting it. The load-bearing word is self-contained: the server doesn't look you up in a session store, it reads you out of the token and confirms the signature hasn't been tampered with. No server-side state. That's the whole trick, and the whole payoff — any instance can validate any token, so you scale horizontally without sharing sessions.

Where it plugs into Spring Security

In Spring Security terms you're adding a filter to the chain, typically a JwtAuthenticationFilter extending OncePerRequestFilter. Its one job: pull the token from the Authorization header, validate it, and if it checks out, set the authenticated identity into the SecurityContext — exactly where the earlier posts said the rest of the app reads it from. You also tell Spring Security the session policy is stateless: don't create sessions, there's nothing to keep. Slot that filter in ahead of the usual username-and-password filter, and everything downstream — your URL rules, your @PreAuthorize checks — keeps working unchanged, because they only care that someone is authenticated, not how it happened.

The part where people cut themselves

Here's where I get cautious, because JWT is easy to implement and easy to implement badly. A few rules are non-negotiable. First: a JWT is signed, not encrypted. Anyone who intercepts it can read every claim inside, so it travels over HTTPS, always, and you never put secrets in the payload. Second: verify more than the signature. A valid signature only tells you the token wasn't altered; you still check it hasn't expired, and ideally that the issuer and audience are what you expect. Third: keep tokens short-lived. The awkward truth of stateless auth is that you can't easily revoke a token you never stored — a stolen one stays valid until it expires. Short lifetimes plus a separate refresh token is the standard answer: the access token dies in minutes, and you mint a new one using the longer-lived refresh token.

Notice, too, that the CSRF picture flips. Session cookies need CSRF protection; a token you attach explicitly in a header does not, which is why JWT setups switch off the CSRF machinery a cookie-based app depends on. That's not a shortcut — it's a genuinely different threat model.

The trade, stated plainly

JWT is a real fit for APIs, and it is not free. You trade the server's ability to revoke a session instantly for the ability to scale without holding one. That trade is usually right for a public API and usually wrong for a bank's admin console, where being able to kill a session this second matters more than horizontal scale. Knowing which situation you're in — and respecting the HTTPS, expiry, and refresh rules that keep the stateless model honest — is most of the job.

Spring Security

Part 4 of 4

A comprehensive guide to understanding and implementing security in Spring Boot applications using the latest version of Spring Security. Covering authentication, authorization, JWT, OAuth2, and advanced security concepts.

Start from the beginning

Understanding Spring Security: Why It Matters

Security you bolt on at the end is the security you get wrong. Spring Security's whole pitch is treating it as infrastructure instead.