Custom SecurityChainFilter Bean with formLogin(Customizer.withDefaults())
Understanding the basics of Spring Security as a beginner
The code
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api").hasAnyRole("MANAGER")
.requestMatchers("/api/**").hasAnyRole("ADMIN")
.anyRequest().authenticated()
)
.csrf(csrfConfig -> csrfConfig.disable())
.sessionManagement(sessionConfig -> sessionConfig.
sessionCreationPolicy(SessionCreationPolicy.STATELESS));
.formLogin(Customizer.withDefaults());
return httpSecurity.build();
}Now imagine Spring Security is talking to YOU
🟦 Spring Security says:
Hey developer, I am about to protect all HTTP requests in your application.
I will give you my security rule book.
Please tell me the rules.
1️⃣ .authorizeHttpRequests(...)
Spring Security says:
First, tell me which URLs are allowed and who can access them.
You reply using the rule book:
auth -> authSpring Security:
Here is my URL-rules notebook.
Write your access rules in it.
You write:
.requestMatchers("/api").hasAnyRole("MANAGER")Spring Security understands:
If someone accesses
/api,
allow only users who have MANAGER role.
You write:
.requestMatchers("/api/**").hasAnyRole("ADMIN")Spring Security understands:
If someone accesses
/apior anything under it,
allow only users who have ADMIN role.
You write:
.anyRequest().authenticated()Spring Security understands:
For every other URL,
user must be logged in (any role is fine).
Spring Security responds:
Got it.
I’ve saved all your URL access rules.
2️⃣ .csrf(csrfConfig -> csrfConfig.disable())
Spring Security says:
By default, I protect your app against CSRF attacks.
You reply:
csrfConfig.disable()Spring Security understands:
Okay, you don’t want CSRF protection.
I will NOT check CSRF tokens for requests.
Spring Security notes:
This usually means you are building APIs or token-based auth.
3️⃣ .sessionManagement(...)
Spring Security says:
How should I manage login state?
Should I store it in server session or not?
You reply:
sessionCreationPolicy(STATELESS)Spring Security understands:
Do NOT create or use HTTP sessions.
I will NOT store login info on server.
Every request must prove who it is.
Spring Security notes:
This is stateless security (JWT / API style).
4️⃣ .formLogin(Customizer.withDefaults())
Spring Security says:
Should I provide a login form for browser users?
You reply:
withDefaults()Spring Security understands:
Yes.
Use my default login page.
Use/loginendpoint.
Handle username/password automatically.
5️⃣ After reading everything, Spring Security says:
Thank you.
I will now build my security filters using your rules.
I will enforce these rules for every HTTP request.
🔁 What happens at runtime (simple)
When a request comes:
- Spring Security checks URL rules
- Checks role requirement
- Skips CSRF check (because you disabled it)
- Does NOT create a session
- If needed, shows login form
- Allows or blocks request
🧠 One-paragraph summary
In this configuration, Spring Security protects all URLs.
/apiis allowed only for MANAGER,/api/**only for ADMIN, and everything else requires login. CSRF protection is turned off, sessions are disabled, and default login form is enabled. Spring Security uses these rules to build its internal filters and enforce security for every request.
Very important rule:
The login page exists ONLY if
formLogin()is enabled.
formLogin()
→ enables login page
→ enablesUsernamePasswordAuthenticationFilter
→ enables session-based login
When you comment on it:
- ❌ no login page
- ❌ no
/loginendpoint - ❌ no username/password form flow
Spring Security is not “broken” — it is obeying you.
Note:
A form login requires a session to remember the logged-in user.
Get Raushan Kumar’s stories in your inbox
Join Medium for free to get updates from this writer.
So from Spring’s view:
Form login + STATELESS makes no sense.
That’s why in real projects:
- Form login → stateful (session-based)
- Stateless → token-based (JWT, API key, etc.)





