Summary
A migration from Spring Security 5 → 7 caused the login form submission to return HTTP 404.
The root issue is that Spring Security 7 no longer uses WebSecurityConfigurerAdapter, and the old .loginProcessingUrl() and .antMatchers() configuration no longer registers the login endpoint. As a result, the POST to the login URL is not mapped, producing a 404.
Root Cause
The failure occurs because Spring Security 6+ removed several APIs, including:
WebSecurityConfigurerAdapterantMatchers()authorizeRequests()formLogin().loginProcessingUrl()- Implicit registration of the login POST endpoint
In Spring Security 7, the login processing endpoint must be configured using the new Lambda DSL, and the login page URL cannot be reused as the login-processing URL.
Why This Happens in Real Systems
Real-world migrations break because:
- Security filter chains are rebuilt from scratch in Spring Security 6+
- Old configuration silently stops working, but compiles if you keep legacy imports
- Login POST endpoints are no longer auto-registered
- URL matching rules changed, so old patterns like
"**"orantMatchers()do nothing
Real-World Impact
Teams commonly experience:
- 404 on login POST (most common)
- 403 on protected pages
- Login page loads but authentication never triggers
- Logout URL not registered
- Custom handlers never invoked
These failures often appear only after deployment, making them costly.
Example or Code (if necessary and relevant)
Below is a minimal Spring Security 7 equivalent of your old configuration.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.cors(cors -> {})
.authorizeHttpRequests(auth -> auth
.requestMatchers(aAnonymousPage_).anonymous()
.requestMatchers(aAuthenticatedPage_).authenticated()
.anyRequest().permitAll()
)
.formLogin(form -> form
.loginPage(sLoginPage_)
.loginProcessingUrl("/login") // MUST be a POST endpoint, not the same as loginPage
.successHandler(authenticationSuccessHandler(sLoginSuccessUrl_))
.failureHandler(authenticationFailureHandler(sLoginPage_))
)
.logout(logout -> logout
.logoutUrl(sLogoutUrl_)
.logoutSuccessHandler(logoutSuccessHandler(sLoginPage_))
.deleteCookies("JSESSIONID")
);
return http.build();
}
How Senior Engineers Fix It
Experienced engineers resolve this by:
- Rewriting the entire security config using the new Lambda DSL
- Separating loginPage URL from loginProcessingUrl
- Ensuring POST
/loginexists and is not blocked - Replacing antMatchers with requestMatchers
- Defining a SecurityFilterChain bean instead of extending WebSecurityConfigurerAdapter
- Verifying that static resources and anonymous pages are explicitly permitted
They also test:
- GET login page
- POST login processing
- Logout URL
- Redirects and handlers
Why Juniors Miss It
Junior developers often overlook this migration because:
- They assume WebSecurityConfigurerAdapter still works
- They don’t realize loginProcessingUrl must be a POST endpoint
- They expect Spring to auto-register the login filter like before
- They copy old examples that silently fail in Spring Security 7
- They don’t check the Spring Security migration guide, which is essential for 5→7 jumps
The result is a confusing 404 that looks like a controller problem, but is actually a security filter chain misconfiguration.