Error cannot access filter public class securityconfig extends websecurityconfigureradapter

I am trying to implement OAuth2 AuthorizationServer as described in this article but I keep getting the error below. For a spring security config: import org.springframework.beans.factory.annotation.

I am trying to implement OAuth2 AuthorizationServer as described in this article but I keep getting the error below.
For a spring security config:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@Order(1)
class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${user.oauth.user.username}")
    private String username;
    @Value("${user.oauth.user.password}")
    private String password;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatchers()
                .antMatchers("/login", "/oauth/authorize")
                .and()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser(username)
                .password(passwordEncoder().encode(password))
                .roles("USER");
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

I keep getting this error:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project auth-service: Compilation failure
[ERROR] /home/mcs/auth-service/src/main/java/com/example/authservice/config/SecurityConfig.java:[14,1] cannot access javax.servlet.Filter
[ERROR] class file for javax.servlet.Filter not found

What does it mean and what seems to be wrong?

My pom.xml generated form start.spring.io using the latest M2 release for Spring Boot:

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.M2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>auth-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>auth-service</name>
    <description>Authorization service</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>com.okta.spring</groupId>
            <artifactId>okta-spring-boot-starter</artifactId>
            <version>1.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.3.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>2.6.7</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </pluginRepository>
    </pluginRepositories>

</project>

Here is my error of my spring-security-loginform-annotation project

I refer that from mkyong site
link

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project spring-security-loginform-annotation: Compilation failure: Compilation failure:
[ERROR] ProjectsSpringKTspring-security-custom-login-form-annotationsrcmainjavacommkyongconfigSecurityConfig.java:[12,7] error: cannot access Filter
[ERROR] ProjectsSpringKTspring-security-custom-login-form-annotationsrcmainjavacommkyongconfigcoreSpringSecurityInitializer.java:[5,7] error: cannot access ServletException

Here is my details of project

Versions

<spring.version>4.0.6.RELEASE</spring.version>
<spring.security.version>3.2.3.RELEASE</spring.security.version>
<jstl.version>1.2</jstl.version>
<javax.servlet.version>3.1.0</javax.servlet.version>

I run it as like this
mvn clean package install jetty:run

But its gives above error

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {//Line 12

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {//Line 05

asked Aug 1, 2014 at 4:54

Priyan's user avatar

It works, but pom is broken.

When declaring dependency on javax.servlet-api scope is misspelled provider where it should be provided (maven gave me a warning on this before your error).

And no webxml is provided (what is correct), but <failOnMissingWebXml>false</failOnMissingWebXml> is nowhere in pom => maven gave me an error when I had fixed first problem.

I fixed it by adding a new <plugin> declaration in plugins :

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.3</version>
    <configuration>
      <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
  </plugin>

answered Aug 1, 2014 at 8:36

Serge Ballesta's user avatar

Serge BallestaSerge Ballesta

141k11 gold badges119 silver badges241 bronze badges

0

This tutorial will teach you how to migrate from the depricated WebSecurityConfigurerAdapter towards the content-based security configuration.

Spring Security allowed customizing HTTP security by extending a WebSecurityConfigurerAdapter class. This customization included user authorization, user authentication, etc. But in Spring Security 5.7.0-M2 the WebSecurityConfigurerAdapter is deprecated. This is because Spring Framework developers encourage users to move towards content-based security configuration. You can read more about it on Spring Blog.

You might also be interested to learn how to migrate from a depricated autorizeRequests() method.

Spring Security Without the WebSecurityConfigurerAdapter

In this tutorial, I am sharing how to get rid of the warning “the type WebSecurityConfigurerAdapter is deprecated” in the Spring Boot application having Spring Security.

If you use the Spring Boot application, you might use the Spring Configuration class that extends the WebSecurityCofigurerAdapter class. If that’s the case, your code might look like this.

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
         
        // configure HTTP security...
         
    }
 
    @Override
    public void configure(WebSecurity web) throws Exception {
         
        // configure Web security...
         
    }      
}

The above code works well with Spring Security version 5.6.5 or earlier and Spring Boot version 2.6.8 or earlier. But if you use an updated Spring Security or Spring Boot version, you will get the following warning in your IDE.

The type WebSecurityConfigurerAdapter is deprecated

To solve this error, instead of extending WebSecurityConfigurerAdapter and overriding methods for configuring HttpSecurity and WebSecurity, you will have to declare two beans of type SecurityFilterChain and WebSecurityCustomizer. The edit will look like this.

@Configuration
public class SecurityConfiguration {
         
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
     
    }
     
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
         
    }
         
}

Migrating Code Toward the Component-Based Approach

Note:  If you do not want to change your code, then it’s better to not change your Spring Boot or Spring Security version. Keep your Spring Boot version lower than 2.7.0 or your Spring Security version less than 5.7.1.

Now we will migrate a code with security configuration toward a component-based approach. Following is the code which extends WebSecurityConfigurerAdapter class.

With WebSecurityConfigurerAdapter

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurity extends WebSecurityConfigurerAdapter {
...

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                .authorizeHttpRequests()
                .requestMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL).permitAll()
                .anyRequest().authenticated().and()
                .addFilter(getAuthenticationFilter())
                .addFilter(new AuthorizationFilter(authenticationManager(), userRepository))
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.headers().frameOptions().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
    }

    protected AuthenticationFilter getAuthenticationFilter() throws Exception {
        final AuthenticationFilter filter = new AuthenticationFilter(authenticationManager());
        filter.setFilterProcessesUrl("/users/login");
        return filter;
    }
}

And below is the same code without extending WebSecurityConfigurerAdapter class.

Without WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class WebSecurity {

    ...

    @Bean
    public SecurityFilterChain configure(HttpSecurity http) throws Exception {

        // Configure AuthenticationManagerBuilder
        AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
        authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);

        // Get AuthenticationManager
        AuthenticationManager authenticationManager = authenticationManagerBuilder.build();
        http
                .cors().and()
                .csrf().disable().authorizeHttpRequests()
                .requestMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL)
                .permitAll()
                .anyRequest().authenticated().and()
                .addFilter(getAuthenticationFilter(authenticationManager))
                .addFilter(new AuthorizationFilter(authenticationManager, userRepository))
                .authenticationManager(authenticationManager)
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.headers().frameOptions().disable();
        return http.build();
    }

    protected AuthenticationFilter getAuthenticationFilter(AuthenticationManager authenticationManager) throws Exception {
        final AuthenticationFilter filter = new AuthenticationFilter(authenticationManager);
        filter.setFilterProcessesUrl("/users/login");
        return filter;
    }
}

Complete Example of WebSecurity Without WebSecurityConfigurerAdapter

Below is a complete code example of WebSecurity class that does not use the deprecated WebSecurityConfigurerAdapter.

package com.appsdeveloperblog.app.ws.security;

import com.appsdeveloperblog.app.ws.io.repository.UserRepository;

import java.util.Arrays;

import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import com.appsdeveloperblog.app.ws.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class WebSecurity {
    private final UserService userDetailsService;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;
    private final UserRepository userRepository;

    @Autowired
    public WebSecurity(@Qualifier("userService") UserService userDetailsService,
                       BCryptPasswordEncoder bCryptPasswordEncoder,
                       UserRepository userRepository) {
        this.userDetailsService = userDetailsService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
        this.userRepository = userRepository;
    }

    @Bean
    public SecurityFilterChain configure(HttpSecurity http) throws Exception {

        // Configure AuthenticationManagerBuilder
        AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
        authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);

        // Get AuthenticationManager
        AuthenticationManager authenticationManager = authenticationManagerBuilder.build();
        http
                .cors().and()
                .csrf().disable().authorizeHttpRequests()
                .requestMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL)
                .permitAll()
                .requestMatchers(SecurityConstants.H2_CONSOLE)
                .permitAll()
                .anyRequest().authenticated().and()
                
                // User Authentication with custom login URL path 
                .addFilter(getAuthenticationFilter(authenticationManager))

                // User Authorization with JWT 
                .addFilter(new AuthorizationFilter(authenticationManager, userRepository))
                .authenticationManager(authenticationManager)
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        
        http.headers().frameOptions().disable();
        return http.build();
    }

    // Configure custom login URL path
    protected AuthenticationFilter getAuthenticationFilter(AuthenticationManager authenticationManager) throws Exception {
        final AuthenticationFilter filter = new AuthenticationFilter(authenticationManager);
        filter.setFilterProcessesUrl("/users/login");
        return filter;
    }
}

AuthorizationFilter class

Below is a code example of AuthorizationFilter class that will be used to validate the provided Authorization JWT.

package com.appsdeveloperblog.app.ws.security;

import com.appsdeveloperblog.app.ws.io.entity.UserEntity;
import com.appsdeveloperblog.app.ws.io.repository.UserRepository;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import io.jsonwebtoken.Jwts;

public class AuthorizationFilter extends BasicAuthenticationFilter {
    UserRepository userRepository;

    public AuthorizationFilter(AuthenticationManager authManager,
                               UserRepository userRepository) {
        super(authManager);
        this.userRepository = userRepository;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest req,
                                    HttpServletResponse res,
                                    FilterChain chain) throws IOException, ServletException {
        String header = req.getHeader(SecurityConstants.HEADER_STRING);
        if (header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX)) {
            chain.doFilter(req, res);
            return;
        }
        UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        chain.doFilter(req, res);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
        String token = request.getHeader(SecurityConstants.HEADER_STRING);
        if (token != null) {
            token = token.replace(SecurityConstants.TOKEN_PREFIX, "");
            String user = Jwts.parser()
                    .setSigningKey(SecurityConstants.getTokenSecret())
                    .parseClaimsJws(token)
                    .getBody()
                    .getSubject();
            if (user != null) {
                UserEntity userEntity = userRepository.findByEmail(user);
                return new UsernamePasswordAuthenticationToken(user, null, new UserPrincipal(userEntity).getAuthorities());
            }
            return null;
        }
        return null;
    }
}

UserService Interface Implementation

The above code example makes use of UserRepository and UserServiceImpl classes. Below is an example of the UserServiceImpl class.

package com.appsdeveloperblog.app.ws.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import com.appsdeveloperblog.app.ws.io.entity.UserEntity;
import com.appsdeveloperblog.app.ws.io.repository.UserRepository;
import com.appsdeveloperblog.app.ws.service.UserService;

@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    UserRepository userRepository;
    
    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        UserEntity userEntity = userRepository.findByEmail(email);
        if (userEntity == null)
            throw new UsernameNotFoundException(email);
       
        return new User(userEntity.getEmail(), 
                userEntity.getEncryptedPassword(), 
                new ArrayList<>());
    }
}

Main Application file

Below is a code example of the main application file that also creates an instance of BCryptPasswordEncoder.

package com.appsdeveloperblog.app.ws;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@SpringBootApplication
public class MobileAppWsApplication {
    public static void main(String[] args) {
        SpringApplication.run(MobileAppWsApplication.class, args);
    }

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

So that is how you can remove the warning “The type WebSecurityConfigurerAdapter is deprecated” in your Spring Boot applications with Spring Security. You mainly need to declare SecurityFilterChain and WebSecurityCustomizer beans instead of overriding methods of WebSecurityConfigurerAdapter class.

I hope this code example was of some help to you. Let me know if you have questions in the comments below. Check out the Spring Boot tutorials page to learn more about Spring Boot.

Happy learning!

From Spring Boot 2.7, WebSecurityConfigurerAdapter is deprecated. In this tutorial, I will show you how to update your Web Security Config class in Spring Security without the WebSecurityConfigurerAdapter example.

Related Posts:
– In-depth Introduction to JWT-JSON Web Token
– Spring Boot, Spring Security example with JWT
– Spring Boot, Spring Security example with JWT and MySQL/PostgreSQL
– Spring Boot, Spring Security example with JWT and MongoDB

Contents

  • With WebSecurityConfigurerAdapter
  • Fix WebSecurityConfigurerAdapter Deprecated in Spring Boot
    • Step 1: Remove WebSecurityConfigurerAdapter
    • Step 2: Export SecurityFilterChain bean
    • Step 3: Replace public configure method
    • AuthenticationManagerBuilder
    • Step 4: Export AuthenticationManager bean
  • Full Code
  • Conclusion
  • Further Reading

We often have the Web Security Config class extend the WebSecurityConfigurerAdapter, export 2 configure() methods and AuthenticationManager bean like this:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  public void configure(WebSecurity web) throws Exception {
    ...
  }

  @Override
  public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
    ...
  }

  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    ...
  }
}

But WebSecurityConfigurerAdapter is Deprecated in Spring Boot 2.7 and later. If you compile the Spring Boot project, you will get the warning:
“The type WebSecurityConfigurerAdapter is deprecated”

Let’s make some steps to remove the Deprecated Warning.

Fix WebSecurityConfigurerAdapter Deprecated in Spring Boot

Step 1: Remove WebSecurityConfigurerAdapter

Firstly, we define the Web Security Config class without WebSecurityConfigurerAdapter and @EnableWebSecurity annotation.

@Configuration
public class WebSecurityConfig {
  ...
}

Step 2: Export SecurityFilterChain bean

Next, instead of using override method configure(HttpSecurity http):

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  ...

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable()
        .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
        .authorizeRequests().antMatchers("/api/auth/**").permitAll()
        .antMatchers("/api/test/**").permitAll()
        .anyRequest().authenticated();

    // http....;
  }
}

We declare SecurityFilterChain bean like this:

@Configuration
public class WebSecurityConfig {

  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable()
        .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
        .authorizeRequests().antMatchers("/api/auth/**").permitAll()
        .antMatchers("/api/test/**").permitAll()
        .anyRequest().authenticated();
    
    // http....;
    
    return http.build();
  }

Step 3: Replace public configure method

There are two public configure() methods:

  • configure(WebSecurity)
  • configure(AuthenticationManagerBuilder)

Instead of using configure(WebSecurity web):

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  ...

  @Override
  public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/js/**", "/images/**"); 
  }
}

We export WebSecurityCustomizer bean

@Configuration
public class WebSecurityConfig {
  ...

  @Bean
  public WebSecurityCustomizer webSecurityCustomizer() {
    return (web) -> web.ignoring().antMatchers("/js/**", "/images/**"); 
  }
}

AuthenticationManagerBuilder

Instead of using configure(AuthenticationManagerBuilder):

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  ...

  @Override
  public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
    authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
  }
}

We export DaoAuthenticationProvider bean (child of AuthenticationProvider), and pass it to HttpSecurity’s authenticationProvider() method:

@Configuration
public class WebSecurityConfig {
  ...

  @Bean
  public DaoAuthenticationProvider authenticationProvider() {
      DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
       
      authProvider.setUserDetailsService(userDetailsService);
      authProvider.setPasswordEncoder(passwordEncoder());
   
      return authProvider;
  }

  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    // http....;
    
    http.authenticationProvider(authenticationProvider());

    // http....;
    
    return http.build();
}

Step 4: Export AuthenticationManager bean

To export AuthenticationManager bean, instead of overriding authenticationManagerBean() method:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  ...

  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }
}

We call getAuthenticationManager() function of AuthenticationConfiguration that returns an AuthenticationManager object:

@Configuration
public class WebSecurityConfig {
  ...

  @Bean
  public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfiguration) throws Exception {
    return authConfiguration.getAuthenticationManager();
  }
}

Full Code

After all, this is full updated code for example:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.bezkoder.spring.security.jwt.AuthEntryPointJwt;
import com.bezkoder.spring.security.jwt.AuthTokenFilter;
import com.bezkoder.spring.security.services.UserDetailsServiceImpl;

@Configuration
@EnableGlobalMethodSecurity(
    // securedEnabled = true,
    // jsr250Enabled = true,
    prePostEnabled = true)
public class WebSecurityConfig { // extends WebSecurityConfigurerAdapter {
  @Autowired
  UserDetailsServiceImpl userDetailsService;

  @Autowired
  private AuthEntryPointJwt unauthorizedHandler;

  @Bean
  public AuthTokenFilter authenticationJwtTokenFilter() {
    return new AuthTokenFilter();
  }

//  @Override
//  public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
//    authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
//  }
  
  @Bean
  public DaoAuthenticationProvider authenticationProvider() {
      DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
       
      authProvider.setUserDetailsService(userDetailsService);
      authProvider.setPasswordEncoder(passwordEncoder());
   
      return authProvider;
  }

//  @Bean
//  @Override
//  public AuthenticationManager authenticationManagerBean() throws Exception {
//    return super.authenticationManagerBean();
//  }
  
  @Bean
  public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
    return authConfig.getAuthenticationManager();
  }

  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }

//  @Override
//  protected void configure(HttpSecurity http) throws Exception {
//    http.cors().and().csrf().disable()
//      .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
//      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
//      .authorizeRequests().antMatchers("/api/auth/**").permitAll()
//      .antMatchers("/api/test/**").permitAll()
//      .anyRequest().authenticated();
//
//    http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
//  }
  
  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable()
        .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
        .authorizeRequests().antMatchers("/api/auth/**").permitAll()
        .antMatchers("/api/test/**").permitAll()
        .anyRequest().authenticated();
    
    http.authenticationProvider(authenticationProvider());

    http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    
    return http.build();
  }
}

Conclusion

Currently, if you want to use WebSecurityConfigurerAdapter, just downgrade Spring Boot to 2.6 or older versions. But take note that WebSecurityConfigurerAdapter is getting deprecated in Spring Boot for new approach: Component-based security configuration, and you may need to update your Web Security Config class in Spring Security without the WebSecurityConfigurerAdapter.

Further Reading

  • Spring Security Reference
  • Spring Boot Rest API CRUD example
  • Spring Boot Pagination and Sorting example
  • Spring Boot File upload example with Multipart File
  • CRUD GraphQL APIs example with Spring Boot & Spring JPA
  • Spring Boot Rest XML example – Web service with XML Response
  • @RestControllerAdvice example in Spring Boot
  • Spring Boot @ControllerAdvice & @ExceptionHandler example
  • Spring Boot Unit Test for Rest Controller

Associations:

  • JPA One To One example with Hibernate in Spring Boot
  • JPA One To Many example with Hibernate and Spring Boot
  • JPA Many to Many example with Hibernate in Spring Boot

Fullstack:

  • Spring Boot + Vuejs: JWT Authentication Example
  • Spring Boot + Angular 8: JWT Authentication Example
  • Spring Boot + Angular 10: JWT Authentication Example
  • Spring Boot + Angular 11: JWT Authentication Example
  • Spring Boot + Angular 12: JWT Authentication example
  • Spring Boot + Angular 13: JWT Authentication example
  • Spring Boot + Angular 14: JWT Authentication example
  • Spring Boot + React.js: JWT Authentication example

Deployment:

  • Deploy Spring Boot App on AWS – Elastic Beanstalk
  • Docker Compose: Spring Boot and MySQL example

When configuring your spring boot application to use netty as embedded http server, the code fails to compile due to missing dependencies. When extending the WebSecurityConfigurerAdapter or the BasicAuthenticationEntryPoint, the following errors occur:

@Configuration
@EnableWebSecurity
public class ABCConfig extends WebSecurityConfigurerAdapter {
..
}

Error:(21, 8) java: cannot access javax.servlet.Filter
class file for javax.servlet.Filter not found

@Component
public class BasicAuthenticationPoint extends BasicAuthenticationEntryPoint {
..
}

Error:(7, 8) java: cannot access javax.servlet.ServletException
class file for javax.servlet.ServletException not found

Gradle Configuration:

spring-boot-gradle-plugin:2.0.1.RELEASE


...
configurations.compile {
    exclude module: 'spring-boot-starter-tomcat'
}
dependencies{
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-reactor-netty")
    compile("org.springframework.boot:spring-boot-starter-webflux")
    compile("org.springframework.boot:spring-boot-starter-security")
...
}

Including the servlet-api dependency (javax.servlet:javax.servlet-api:3.0.1) fixes the compile problem but the server start fails because no implementation of the ServletWebServerFactory is provided. The console output looks as following:

2018-04-25 12:28:00.695 ERROR 19594 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155) ~[spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544) ~[spring-context-5.0.5.RELEASE.jar:5.0.5.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]

The mentioned examples above work with Tomcat as well as with Jetty. I would expect it to work with Netty as well.

Вот моя ошибка в моем проекте Spring-security-loginform-annotation

Я имею в виду, что с mkyong сайта ссылка

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project spring-security-loginform-annotation: Compilation failure: Compilation failure:
[ERROR] ProjectsSpringKTspring-security-custom-login-form-annotationsrcmainjavacommkyongconfigSecurityConfig.java:[12,7] error: cannot access Filter
[ERROR] ProjectsSpringKTspring-security-custom-login-form-annotationsrcmainjavacommkyongconfigcoreSpringSecurityInitializer.java:[5,7] error: cannot access ServletException

Вот мои подробности проекта

Версии

<spring.version>4.0.6.RELEASE</spring.version>
<spring.security.version>3.2.3.RELEASE</spring.security.version>
<jstl.version>1.2</jstl.version>
<javax.servlet.version>3.1.0</javax.servlet.version>

Я запускаю его так, как этот mvn clean package install jetty: run

Но это дает выше ошибку

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {//Line 12

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {//Line 05

Иногда требуется, чтобы в приложении для разных url была настроена разная аутентификация и авторизация. Одну часть приложения надо обезопасить так, а другую этак.

Например, по адресам /api/* приложение предоставляет REST API с аутентификацией через JWT-токен. А все остальные url — это обычные страницы веб-сайта с перенаправлением на форму логина для неаутентифицированных, используют сессии.

Или же для каких-то url аутентификация будет базовая (Http Basic), а для остальных — обычная форма для входа (Form-Based). Именно такой пример мы и напишем.

По сути для разных url будет настроена разная цепочка фильтров, через которые проходит запрос. Чтобы такое реализовать, нужно настроить два бина HttpSecurity, а для этого дважды расширить класс WebSecurityConfigurerAdapter и переопределить в нем метод:

public class SecurityConfig extends WebSecurityConfigurerAdapter{
    ... 

    config(HttpSecurity http){
     ...
    }
}

Все то же, что в предыдущей статье, только дважды.

Задача

Мы решим такую задачу:

  1. Для  адресов /admin/** работает Http Basic аутентификация. Еще эти url будут доступны только для администратора.
  2. Для всех остальных url работает Form-Based аутентификация (если аутентификация нужна). Нужна она для /user — этот url доступен только для ролей пользователя и администратора.

Итак, напишем две конфигурации для этих двух пунктов:

@EnableWebSecurity 
//одна конфигурация
public class SecurityConfig extends WebSecurityConfigurerAdapter {


   //здесь будет настройка аутентификации 

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .antMatcher("/**")
                .authorizeRequests(a -> a
                        .antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
                        .anyRequest().permitAll())
                .formLogin();

    }


    @Configuration
    // другая конфигурация - приоритетная
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public static class AnotherSecurityConfig extends WebSecurityConfigurerAdapter {


        @Override
        protected void configure(HttpSecurity http) throws Exception {

            http
                    .antMatcher("/admin/**")
                    .authorizeRequests(a -> a.anyRequest().hasAnyRole("ADMIN"))
                    .httpBasic();

        }
    }

}

Конфигурация для п. 1 сделана как статический вложенный класс — это обычный класс, но так он компактно помещается на страницу внутри другого. Его можно вынести и в отдельный файл без слова static.

Отличаются конфигурации тем, что в первой используется Form-Based аутентификация:

Form-Based по адресу localhost:8080/user

Form-Based по адресу localhost:8080/user

а во второй — Http Basic:

Http Basic по адресу localhost:8080/admin

Http Basic по адресу localhost:8080/admin

Можно было сделать JWT-авторизацию для одной из конфигураций, про JWT есть статья. Там в HttpSecurity добавлен фильтр:

http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);

Суть в том, что можно задать совершенно разные HttpSecurity для разных url, при этом разные запросы будут проходить через разные цепочки фильтров.

В классе SecurityConfig задан HttpSecurity для всех url:

htpp.antMatcher("/**")

а в классе AnotherSecurityConfig задан HttpSecurity для url, начинающихся с /admin:

htpp.antMatcher("/admin/**")

Обратите внимание, что метод тут называется antMatcher(..), а не antMatchers(..), разница в букву, но второй используется уже внутри для выдачи разрешений, а первый задает, для каких url собран весь HttpSecurity.

Как задать приоритет: какую HttpSecurity проверять первой на предмет соответствия запросу

То есть когда приходит запрос, приложение проверяет, соответствует ли он шаблону в htpp. antMatcher(…). И если да, применяет для пришедшего  запроса данный http.

При этом сначала оно проверяет конфигурацию  AnotherSecurityConfig, так как ее приоритет выше.

Приоритет задается с помощью аннотации @Order(Ordered.HIGHEST_PRECEDENCE)

То есть, например, если придет запрос /admin, то приложение в первую очередь проверит конфигурацию AnotherSecurityConfig.  В ней задан шаблон «/admin/**», и путь /admin удовлетворяет шаблону. Так что для запроса конфигурация AnotherSecurityConfig выиграет несмотря на то, оба шаблона подходят: как  в AnotherSecurityConfig, так и в SecurityConfig.

Общие пользователи для двух конфигураций

Важно отметить, что пользователи должны быть общие для обеих конфигураций, а значит настроить AuthenticationManagerBuilder переопределением метода config(AuthenticationManagerBuilder auth), как это мы делали в предыдущей статье, не получится (иначе в каком из классов его переопределять). Вместо этого создадим метод configGlobal (можно назвать его как угодно) и внедрим в него AuthenticationManagerBuilder:

@EnableWebSecurity 
//одна конфигурация 
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...    
    @Autowired
    public void configGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user")
                .password("password")
                .authorities("ROLE_USER")
                .and()
                .withUser("admin")
                .password("password")
                .authorities("ROLE_ADMIN");
    }
}

Так пользователи user и admin будут действовать для обеих конфигураций HttpSecurity.

Альтернативный способ задать пользователей

Как вариант, общих пользователей можно задать UserDetailsService:

    @Bean
    public UserDetailsService userDetailsService() {
        // ensure the passwords are encoded properly
        User.UserBuilder users = User.withDefaultPasswordEncoder();
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(users.username("user").password("password")
                .roles("USER").build());
        manager.createUser(users.username("admin").password("password")
                .roles("ADMIN").build());
        return manager;
    }

В последнем случае бин PasswordEncoder в конфигурации НЕ нужен:

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

Исходный код доступен на GitHub.

Details
Written by  
Last Updated on 21 July 2022   |   Print  Email

In this short article, I’d like to share how to get rid of the warning saying that “The type WebSecurityConfigurerAdapter is deprecated” in Spring-based application with Spring Security.

Perhaps you are used to have a Spring configuration class that extends the WebSecurityConfigurerAdapter abstract class like this:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		
		// configure HTTP security...
		
	}

	@Override
	public void configure(WebSecurity web) throws Exception {
		
		// configure Web security...
		
	}		
}

This is fine with Spring Security version 5.6.5 or older, or with Spring Boot version 2.6.8 or older. However, if your project uses Spring Security 5.7.1 or newer, or Spring Boot 2.7.0 or newer, you will get this warning in your IDE:

The type WebSecurityConfigurerAdapter is deprecated

So, why Spring Security deprecates the use of WebSecurityConfigurerAdapter ?, and what is the alternative?

Well, it’s because the developers of Spring framework encourage users to move towards a component-based security configuration.

So, instead of extending WebSecurityConfigurerAdapter and overriding methods for configuring HttpSecurity and WebSecurity as in the old way — Now you to declare two beans of type SecurityFilterChain and WebSecurityCustomizer as follows:

@Configuration
public class SecurityConfiguration {
		
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
	
    }
    
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        
    }
        
}

For your reference, below is a code example of migrating security configuration towards component-based approach. First, let’s look at a typical security configuration class with WebSecurityConfigurerAdapter as shown below:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Bean
	public UserDetailsService userDetailsService() {
		return new ShopmeUserDetailsService();
	}

	@Bean
	public BCryptPasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests().antMatchers("/login").permitAll()
				.antMatchers("/users/**", "/settings/**").hasAuthority("Admin")
				.hasAnyAuthority("Admin", "Editor", "Salesperson")
				.hasAnyAuthority("Admin", "Editor", "Salesperson", "Shipper")
				.anyRequest().authenticated()
				.and().formLogin()
				.loginPage("/login")
					.usernameParameter("email")
					.permitAll()
				.and()
				.rememberMe().key("AbcdEfghIjklmNopQrsTuvXyz_0123456789")
				.and()
				.logout().permitAll();

		http.headers().frameOptions().sameOrigin();	
	}
	
	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**");	
	}
}

And below is an alternative, without WebSecurityConfigurerAdapter:

package net.codejava;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfiguration {

	@Bean
	public UserDetailsService userDetailsService() {
		return new ShopmeUserDetailsService();
	}

	@Bean
	public BCryptPasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
	
		http.authorizeRequests().antMatchers("/login").permitAll()
				.antMatchers("/users/**", "/settings/**").hasAuthority("Admin")
				.hasAnyAuthority("Admin", "Editor", "Salesperson")
				.hasAnyAuthority("Admin", "Editor", "Salesperson", "Shipper")
				.anyRequest().authenticated()
				.and().formLogin()
				.loginPage("/login")
					.usernameParameter("email")
					.permitAll()
				.and()
				.rememberMe().key("AbcdEfghIjklmNopQrsTuvXyz_0123456789")
				.and()
				.logout().permitAll();

		http.headers().frameOptions().sameOrigin();

		return http.build();
	}

	@Bean
	public WebSecurityCustomizer webSecurityCustomizer() {
		return (web) -> web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**");
	}

}

 

Declare a bean of type AuthenticationManager: 

In case you need to expose a bean of type AuthenticationManager, you can put the following code:

@Bean
public AuthenticationManager authenticationManager(
		AuthenticationConfiguration authConfig) throws Exception {
	return authConfig.getAuthenticationManager();
}

 

Declare a bean of type AuthenticationProvider:

In case you need to expose a bean of type AuthenticationProvider, such as DaoAuthenticationProvider, use the following code:

@Bean
public DaoAuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    
    authProvider.setUserDetailsService(userDetailsService());
    authProvider.setPasswordEncoder(passwordEncoder());

    return authProvider;
}

and specify this authentication provider for HttpSecurity in the code of SecurityFilterChain as follows:

 http.authenticationProvider(authenticationProvider());

 

That’s how to remove the warning “The type WebSecurityConfigurerAdapter is deprecated” in Spring-based application with Spring Security. You need to declare SecurityFilterChain and WebSecurityCustomizer beans instead of overriding methods of WebSecurityConfigurerAdapter class.

 

NOTE: If you don’t want to change your current code, you should keep Spring Boot version lower than 2.7.0 or Spring Security version older than 5.7.1.

I hope you have found this post helpful. Thanks for reading.

Reference: Spring Security without the WebSecurityConfigurerAdapter

 

Spring Tutorials:

  • Spring Framework Tutorials
  • Spring Boot Tutorials
  • Spring Security Tutorials

About the Author:

Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.

Add comment

Getting deprecated warning or issue when extends WebSecurityConfigurerAdapter in Spring Boot. This is because WebSecurityConfigurerAdapter is no longer recommended. The alternative for this is SecurityFilterChain class.

In this tutorial, you will learn how to remove or resolve the WebSecurityConfigurerAdapter deprecated warning and instead implement SecurityFilterChain in your spring boot application.

Solve WebSecurityConfigurerAdapter Deprecated

Bellow are the some warning we get while compiling the project.

Deprecated
Use a org.springframework.security.web.SecurityFilterChain Bean to configure HttpSecurity or a WebSecurityCustomizer Bean to configure WebSecurity
Note: SecurityConfig.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

Spring Security: Upgrading the deprecated WebSecurityConfigurerAdapter in Spring Boot 2.7.0

Bellow is the Example of WebSecurityConfig.java which i created in my Login Register Example in Spring Boot Tutorial.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Bean
    public UserDetailsService userDetailsService() {
        return new ShopmeUserDetailsService();
    }
 
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
     
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/login").permitAll()
                 .antMatchers("/users/**", "/settings/**").hasAuthority("Admin")
                .hasAnyAuthority("Admin", "USER")
                .hasAnyAuthority("Admin", "USER")
                .anyRequest().authenticated()
                .and().formLogin()
                .loginPage("/login")
                .usernameParameter("email")
                .permitAll()
                .and()
                .logout().permitAll();
    }
     
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**"); 
    }
}

and bellow is alternative of WebSecurityConfig.java without extending WebSecurityConfigurerAdapter

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfiguration {

    @Bean
    public UserDetailsService userDetailsService() {
        return new ShopmeUserDetailsService();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
     
        http.authorizeRequests().antMatchers("/login").permitAll()
                .antMatchers("/users/**", "/settings/**").hasAuthority("Admin")
                .hasAnyAuthority("Admin", "USER")
                .hasAnyAuthority("Admin", "USER")
                .anyRequest().authenticated()
                .and().formLogin()
                .loginPage("/login")
                .usernameParameter("email")
                .permitAll()
                .and()
                .logout().permitAll();
 
        return http.build();
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**");
    }

}

Optional Part (Incase you have implemented then): If you are using AuthenticationManger Bean.

@Bean
public AuthenticationManager authenticationManager(
        AuthenticationConfiguration authConfig) throws Exception {
    return authConfig.getAuthenticationManager();
}

Optional Part (Incase you have implemented then): If you are using DaoAuthenticationProvider Bean.

@Bean
public DaoAuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
     
    authProvider.setUserDetailsService(userDetailsService());
    authProvider.setPasswordEncoder(passwordEncoder());
 
    return authProvider;
}

and add this authentication provider for HttpSecurity in the code of SecurityFilterChain as follows:

http.authenticationProvider(authenticationProvider());

Bellow is full file example from my Login Register for Spring Tutorial

package com.example.demo.config;

import com.example.demo.service.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Autowired
    private CustomLoginSucessHandler sucessHandler;

    @Bean
    public UserDetailsService userDetailsService() {
        return new UserServiceImpl();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();

        authProvider.setUserDetailsService(userDetailsService());
        authProvider.setPasswordEncoder(passwordEncoder());

        return authProvider;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

                http.authorizeRequests()
                // URL matching for accessibility
                .antMatchers("/", "/login", "/register").permitAll()
                .antMatchers("/admin/**").hasAnyAuthority("ADMIN")
                .antMatchers("/account/**").hasAnyAuthority("USER")
                .anyRequest().authenticated()
                .and()
                // form login
                .csrf().disable().formLogin()
                .loginPage("/login")
                .failureUrl("/login?error=true")
                .successHandler(sucessHandler)
                .usernameParameter("email")
                .passwordParameter("password")
                .and()
                // logout
                .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/")
                .and()
                .exceptionHandling()
                .accessDeniedPage("/access-denied");

                http.authenticationProvider(authenticationProvider());
                http.headers().frameOptions().sameOrigin();

                return http.build();
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().antMatchers("/images/**", "/js/**", "/webjars/**");
    }

}

Find this on Github

Понравилась статья? Поделить с друзьями:
  • Error canceling statement due to conflict with recovery
  • Error canceling autovacuum task
  • Error can t start driver error 1275
  • Error can t read profile path
  • Error can t read or write variables of this type