CodeGym /Courses /Module 5. Spring /The @EnableWebSecurity annotation and what it does

The @EnableWebSecurity annotation and what it does

Module 5. Spring
Level 17 , Lesson 3
Available

Spring Security is a really powerful tool, but to start using it in your project you need to turn on the security machinery. The @EnableWebSecurity annotation, as the name suggests, does exactly that.

In short, @EnableWebSecurity:

  • enables the use of Spring Security in your application.
  • hooks up security configuration either via the WebSecurityConfigurerAdapter class or directly via SecurityFilterChain.
  • initializes Spring Security filters to handle all incoming HTTP requests.

Without it, Spring Security will sit in your project like a museum piece — nice to look at but not very useful. Let's see how it works and why it's so important.


What happens after you add @EnableWebSecurity?

Want to know what happens when you add @EnableWebSecurity to your code? Spring Security wakes up and starts guarding your app! Let's peek under the hood of that magic:

  1. Spring creates a chain of security filters — basically a checkpoint for all incoming requests. Each request now goes through this security system before it reaches your application.
  2. Spring Security immediately enables basic protection — like putting locks on all the doors. By default all HTTP resources become locked down, and without the right "keys" (authentication) you can't get to them.
  3. And the coolest part — you can customize this security system to fit your needs! Want to add your own checks? Use SecurityFilterChain.

And if you're curious about history, people used to do this with WebSecurityConfigurerAdapter (though since version 5.7 it's pretty much considered vintage).


Basics of configuration with @EnableWebSecurity

Here's an example of the minimal security configuration:


import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    // Config is empty for now, but security is already turned on!
}

If you run this app and try to access any of your resource or controller URLs, you'll notice Spring Security automatically redirects you to a login page. That's the default behavior, provided out-of-the-box.

Customizing the configuration

Let's add some meaningful customization. We can override settings using a SecurityFilterChain bean:

Example with custom rules:


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests() // Configure request authorization
                .antMatchers("/public/**").permitAll() // Allow access to all URLs starting with /public
                .anyRequest().authenticated() // All other requests require authentication
            .and()
            .formLogin() // Enable the standard login form
                .loginPage("/login") // Custom login page
                .permitAll()
            .and()
            .logout() // Enable the standard logout
                .permitAll();
        return http.build();
    }
}

Let's break down what this code does:

  1. Restricting access by URL: the antMatchers methods let you define access based on specific URLs. For example, all requests to /public are allowed without authentication.
  2. Login form: we've customized the default login form by pointing to our page with loginPage. Now users will see your custom UI instead of the default login page.
  3. Logout: we allow any user to perform logout.

After adding this configuration, your app will be protected in a more meaningful way than with Spring Security's basic defaults.


Why was WebSecurityConfigurerAdapter needed?

We already mentioned that before Spring Security 5.7, security customization was usually done by extending WebSecurityConfigurerAdapter. Here's what that looked like:


import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
            .logout()
                .permitAll();
    }
}

If you still see this approach in old code — don't freak out. But get used to using SecurityFilterChain, since that approach is more modern.


Examples of basic security setup

1. Simple example where all pages are protected:


@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
            .and()
            .formLogin() // Enable login form
            .and()
            .httpBasic(); // This adds support for HTTP Basic authentication
        return http.build();
    }
}

Now when trying to access any resource, the user will have to either enter credentials in the browser or authenticate via HTTP Basic.

2. Example with public resources:


@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/css/**", "/js/**", "/images/**").permitAll() // Open static resources
                .antMatchers("/", "/home").permitAll() // Open the home page
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
            .logout()
                .permitAll();
        return http.build();
    }
}

This example lets certain public resources (like static assets or the home page) be viewed, while protecting everything else.


Common mistakes and how to fix them

  1. Mistake: you lock down everything, including the login page. If you configure things incorrectly, you might accidentally block access to your own login page. Make sure the login page (or other public resources) is explicitly allowed via permitAll().
  2. Mistake: you forgot to add @EnableWebSecurity. Without that annotation your configuration won't be applied and the app just won't be secured.
  3. Mistake: using the outdated WebSecurityConfigurerAdapter approach. With the move to the modern SecurityFilterChain, a lot of online examples can be misleading. Use newer Spring Security versions to avoid compatibility issues.

Practice: setting up a basic configuration

Let's add security to our tutorial app. Imagine we have a web app for managing books. We need to:

  1. Create a login page.
  2. Allow everyone to access /login and /register.
  3. Protect access to all other pages.

Configuration:


@Configuration
@EnableWebSecurity
public class BookAppSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/login", "/register").permitAll() // Access for everyone
                .anyRequest().authenticated() // Everything else requires authentication
            .and()
            .formLogin() // Enable the standard login form
                .loginPage("/login") // Point to custom login page
                .permitAll()
            .and()
            .logout()
                .permitAll(); // Logout is available to everyone
        return http.build();
    }
}

Now our app is secure: users can register or log in, but without authentication access to other pages is blocked.


Link to the Spring Security documentation to dig deeper.

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION