spring-security
disable-login-screen
authentication
web-security
spring-boot

How to disable spring-security login screen?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

To disable the default Spring Security login screen, call .formLogin(AbstractHttpConfigurer::disable) in your SecurityFilterChain bean. This tells Spring Security to stop auto-generating the /login page. The exact configuration depends on your Spring Boot version: Spring Boot 3.x uses the component-based SecurityFilterChain approach, while older 2.x projects may still extend the now-deprecated WebSecurityConfigurerAdapter.

Why the Login Screen Appears

When you add spring-boot-starter-security to your classpath, Spring Boot auto-configures a security filter chain that includes form-based login. This default chain:

  • Protects every endpoint with authentication
  • Generates a login page at /login
  • Creates a single user with a random password printed to the console at startup
  • Enables session-based authentication

This is convenient for prototyping, but most production applications need a different authentication strategy: JWT tokens, OAuth2, API keys, or a custom login UI served by a frontend framework.

The WebSecurityConfigurerAdapter class was removed in Spring Security 6. The modern approach uses a @Bean method that returns a SecurityFilterChain:

java
1import org.springframework.context.annotation.Bean;
2import org.springframework.context.annotation.Configuration;
3import org.springframework.security.config.annotation.web.builders.HttpSecurity;
4import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
5import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
6import org.springframework.security.web.SecurityFilterChain;
7
8@Configuration
9@EnableWebSecurity
10public class SecurityConfig {
11
12    @Bean
13    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
14        http
15            .authorizeHttpRequests(auth -> auth
16                .anyRequest().authenticated()
17            )
18            .formLogin(AbstractHttpConfigurer::disable);
19
20        return http.build();
21    }
22}

This disables the generated login page while keeping all other security features active. Requests to /login will now return a 403 instead of rendering a form.

Spring Boot 2.x / Spring Security 5.x (Legacy)

If you are on an older Spring Boot 2.x project, you may still be using the adapter pattern:

java
1import org.springframework.security.config.annotation.web.builders.HttpSecurity;
2import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
3import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
4
5@EnableWebSecurity
6public class SecurityConfig extends WebSecurityConfigurerAdapter {
7
8    @Override
9    protected void configure(HttpSecurity http) throws Exception {
10        http
11            .authorizeRequests()
12                .anyRequest().authenticated()
13            .and()
14            .formLogin().disable();
15    }
16}

Note that WebSecurityConfigurerAdapter is deprecated since Spring Security 5.7 and removed in 6.0. If you are starting a new project, use the SecurityFilterChain bean approach.

Common Replacement Authentication Strategies

Disabling the login screen is only half the job. You need to replace it with the authentication mechanism your application actually uses.

HTTP Basic Authentication

Suitable for internal services, CLI tools, or APIs behind a gateway:

java
1@Bean
2public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
3    http
4        .authorizeHttpRequests(auth -> auth
5            .anyRequest().authenticated()
6        )
7        .formLogin(AbstractHttpConfigurer::disable)
8        .httpBasic(Customizer.withDefaults());
9
10    return http.build();
11}

Stateless JWT Authentication

For REST APIs where clients send a Bearer token with each request:

java
1@Bean
2public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
3    http
4        .authorizeHttpRequests(auth -> auth
5            .requestMatchers("/api/auth/**").permitAll()
6            .anyRequest().authenticated()
7        )
8        .formLogin(AbstractHttpConfigurer::disable)
9        .sessionManagement(session -> session
10            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
11        )
12        .csrf(AbstractHttpConfigurer::disable)
13        .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
14
15    return http.build();
16}

Stateless APIs disable both form login and session creation. CSRF protection is also typically disabled for stateless APIs because the browser-cookie attack vector does not apply when tokens are sent in headers.

OAuth2 Resource Server

For services that validate tokens issued by an external identity provider:

java
1@Bean
2public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
3    http
4        .authorizeHttpRequests(auth -> auth
5            .anyRequest().authenticated()
6        )
7        .formLogin(AbstractHttpConfigurer::disable)
8        .oauth2ResourceServer(oauth2 -> oauth2
9            .jwt(Customizer.withDefaults())
10        );
11
12    return http.build();
13}

Permit All (Disable Security Entirely)

For local development or when security is handled entirely by an API gateway:

java
1@Bean
2public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
3    http
4        .authorizeHttpRequests(auth -> auth
5            .anyRequest().permitAll()
6        )
7        .formLogin(AbstractHttpConfigurer::disable)
8        .csrf(AbstractHttpConfigurer::disable);
9
10    return http.build();
11}

This is the nuclear option. Never deploy this to production.

Session Management Policies

Once you disable form login, review your session management strategy. The default IF_REQUIRED policy creates sessions when needed, which may not match your new authentication model.

PolicyBehaviorUse Case
STATELESSNo session created or usedJWT APIs, microservices
IF_REQUIREDSession created only when neededTraditional web apps with custom login UI
ALWAYSSession always createdLegacy apps that depend on session state
NEVERSpring Security never creates a session but uses one if it existsServlet-managed sessions

Configure it in your filter chain:

java
.sessionManagement(session -> session
    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)

Disabling Security Auto-Configuration Entirely

If you want to remove Spring Security's auto-configuration completely (not just the login page), you can exclude it at the application level:

java
1@SpringBootApplication(exclude = {
2    SecurityAutoConfiguration.class,
3    ManagementWebSecurityAutoConfiguration.class
4})
5public class MyApplication {
6    public static void main(String[] args) {
7        SpringApplication.run(MyApplication.class, args);
8    }
9}

Or in application.properties:

properties
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration

This removes all security behavior, not just the login page. Use this approach only when you genuinely do not want any security filtering.

Comparison of Approaches

GoalMethodSide Effects
Remove login page only.formLogin(AbstractHttpConfigurer::disable)Endpoints still require authentication; need alternate auth mechanism
Replace with HTTP Basic.httpBasic(Customizer.withDefaults())Browser shows native credential dialog
Replace with JWTCustom filter + STATELESS sessionMust implement token validation; CSRF disabled
Replace with OAuth2.oauth2ResourceServer()Requires external identity provider configuration
Remove all security@SpringBootApplication(exclude = ...)No authentication, no authorization, no CSRF

Common Pitfalls

Calling .formLogin().disable() without providing an alternative authentication mechanism locks you out of every endpoint. Requests fail with 401 or 403, and there is no way to authenticate. Always pair the disable with a replacement strategy.

Using the deprecated WebSecurityConfigurerAdapter in a Spring Boot 3.x project will not compile. The class was removed in Spring Security 6.0. Use the SecurityFilterChain bean pattern instead.

Disabling CSRF globally when your application still uses session-based authentication opens a real security vulnerability. Only disable CSRF for truly stateless APIs where authentication comes from headers, not cookies.

Excluding SecurityAutoConfiguration in production is almost always a mistake. It removes all security, not just the login page. Prefer the targeted .formLogin(AbstractHttpConfigurer::disable) approach.

Forgetting that Spring Boot Actuator has its own security auto-configuration (ManagementWebSecurityAutoConfiguration) means actuator endpoints may still show a login prompt even after you configure your main filter chain.

Summary

  • Disable the default login page with .formLogin(AbstractHttpConfigurer::disable) in a SecurityFilterChain bean (Spring Boot 3.x) or .formLogin().disable() in a WebSecurityConfigurerAdapter override (Spring Boot 2.x).
  • Always replace form login with the authentication mechanism your application actually needs: HTTP Basic, JWT, or OAuth2.
  • Set the session policy to STATELESS for token-based APIs.
  • Avoid excluding SecurityAutoConfiguration entirely unless you genuinely want zero security.
  • Remember that WebSecurityConfigurerAdapter was removed in Spring Security 6.0. Use the bean-based configuration for any new project.

Course illustration
Course illustration

All Rights Reserved.