Skip to main content

Command Palette

Search for a command to run...

How to Set Up Spring Security in Spring Boot 3.x

Add one dependency and everything's locked. The real setup is deciding what to unlock, and why.

Updated
3 min readView as Markdown
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.

The thing that surprises people coming to Spring Security is how little you have to do to start. Add the spring-boot-starter-security dependency, restart the application, and the whole thing is locked. Every endpoint now demands a login. Spring Boot quietly creates a user named "user," prints a random password to the startup logs, and that's your entire app secured before you've written a single line of security code.

That default matters more than it looks. The starting posture is deny everything — which is exactly the right default for security. You want a system where access is granted deliberately, not something you have to remember to take away. Locked-by-default means a forgotten endpoint is safe, not exposed.

Then you replace the defaults with intent

The auto-configuration is a starting point, not a destination. The real setup is telling Spring Security what your actual rules are: which URLs are public, which require a login, and how people authenticate. In Spring Boot 3.x, running on Spring Security 6, you do that by defining a SecurityFilterChain bean.

This is the exact spot where older tutorials lead you wrong. If a guide has you extend WebSecurityConfigurerAdapter, stop — that class was removed in Spring Security 6. The modern approach is a method annotated with @Bean that takes an HttpSecurity object, configures it, and returns the built filter chain. If you learned Spring Security a few years ago, this is the single change that makes everything else look unfamiliar.

The Lambda DSL reads the way the old style should have

The configuration uses what's called the Lambda DSL. Instead of chaining calls together and stitching them with .and(), you pass a small lambda to configure each concern — one for which requests need authorization, one for how login works, and so on. It's marginally more verbose to look at and considerably clearer to read, because each block is visibly self-contained. Inside the authorization block you spell the rules out plainly: these paths permitAll, everything else authenticated. Read top to bottom, it says exactly what it does.

What the defaults handed you for free

It's worth knowing what you inherited without asking, because some of it you'll be tempted to switch off. Out of the box you get CSRF protection, sensible session handling, an expectation that passwords are hashed rather than stored raw, and a set of secure HTTP headers. These are on for good reasons. You can disable any of them, and there are legitimate cases for it — a stateless token API turns off CSRF and server-side sessions deliberately — but "I turned it off because the tutorial did" is not one of those cases.

Where people shoot themselves in the foot

The common failures are all the same shape: opening too much. A permitAll that's broader than intended. A CSRF disable copied without understanding why. A matcher ordered so a permissive rule shadows a stricter one that should have caught the request first. Order matters in the chain — the first rule that matches wins — and it's easy to write rules that quietly never fire.

Setting up Spring Security isn't really about getting it to turn on; it turns on the moment the dependency lands. The work is the opposite of what beginners expect: not adding security, but carefully deciding what to open — and being able to say why for each thing you unlocked.

Spring Security

Part 2 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.

Up next

Understanding Authentication in Spring Security

Under the hood it's five small collaborators, each doing one job — and none of them quite where beginners expect.