1

I am migrating a Spring Boot application from Spring boot 2.6.6 to 3.1.2 in which most of the methods in http security are either deprecated or removed.

I googled a lot of places but I am unable to convert this specific configuration into Spring Boot 3.1.X configuration.

Below are the methods which were written using a class which is extending WebSecurityConfigurerAdapter. Note : preAuthFilter(), accessDeniedHandler() & forbiddenEntryPoint() are methods defined in same class

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/**").exceptionHandling().authenticationEntryPoint(forbiddenEntryPoint())
            .and().authorizeRequests().antMatchers(
                "/**/index*",
                "/**/logout/",
                "/**/logoutApp",
                "/rest/getversion*",
                "/rest/dologin/*",
                "/rest/menu*",
                "/rest/getScript*",
                "/rest/**").permitAll().antMatchers("/rest/saveTodo*").hasRole("ADMIN")
            .antMatchers("/**").denyAll()
            .and()
            .addFilterAt(preAuthFilter(), AbstractPreAuthenticatedProcessingFilter.class)
            .exceptionHandling().accessDeniedHandler(accessDeniedHandler())
            .and().csrf().disable()
            .headers().disable();
    }

@Override
    public void configure(WebSecurity web) {
        web
            .ignoring()
            .antMatchers("/**/*.png*","/**/*.js*","/**/*.jpg*","/**/*.svg*","/**/*.ico*",
                "/**/*.css*","/**/login*","/**/*.woff*","/**/*.ttf*","/**/*.eot*");
    }

I tried changing the above code to below one :

@Bean
public SecurityFilterChain springFilterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(req -> req.requestMatchers(
                new AntPathRequestMatcher(new AntPathRequestMatcher("/**"))))
                    .exceptionHandling(request -> request.authenticationEntryPoint(forbiddenEntryPoint()))
                    .authorizeHttpRequests(request -> request
                            .requestMatchers(
                                    new AntPathRequestMatcher("/**/index*"), 
                                    new AntPathRequestMatcher("/**/logout/"),
                                    new AntPathRequestMatcher("/**/logoutApp"), 
                                    new AntPathRequestMatcher("/rest/getversion*"),
                                    new AntPathRequestMatcher("/rest/dologin/*"),
                                    new AntPathRequestMatcher("/rest/menu*"),
                                    new AntPathRequestMatcher("/rest/getScript*"), 
                                    new AntPathRequestMatcher("/rest/**"),
                                    new AntPathRequestMatcher("/waveinventoryservice/**"))
                            .permitAll()
                            .requestMatchers(new AntPathRequestMatcher("/rest/saveTodo*")).hasRole("ADMIN")
                            .requestMatchers(new AntPathRequestMatcher("/**"))
                            .denyAll())
                    .addFilterAt(preAuthFilter(), AbstractPreAuthenticatedProcessingFilter.class)
                    .exceptionHandling(handler -> handler.accessDeniedHandler(accessDeniedHandler()))
                    .csrf(CsrfConfigurer::disable).headers(HeadersConfigurer::disable).build();
}

@Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().requestMatchers(new AntPathRequestMatcher("/**/*.png*"),
                new AntPathRequestMatcher("/**/*.js*"),
                new AntPathRequestMatcher("/**/*.jpg*"),
                new AntPathRequestMatcher("/**/*.svg*"),
                new AntPathRequestMatcher("/**/*.ico*"),
                new AntPathRequestMatcher("/**/*.css*"),
                new AntPathRequestMatcher("/**/login*"),
                new AntPathRequestMatcher("/**/*.woff*"),
                new AntPathRequestMatcher("/**/*.ttf*"),
                new AntPathRequestMatcher("/**/*.eot*"));
    }

this code seems to be not working because I'm getting null in the controllers & filters on invoking the method : SecurityContextHolder.getContext().getAuthentication() even after setting it in one api with URL "rest/dologin/{userId}"

previously with the old configuration it was working but not now, can someone please try to help me out in changing this configuration?

3 Answers3

0

I had made security configuration in spring boot 3 maybe that can help you

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {

    private final JwtFilter jwtFilter;
    private final JwtAuthenticationEntryPoint authenticationEntryPoint;
    private final JWTAccessDeniedHandler accessDeniedHandler;

    public SecurityConfig(JwtFilter jwtFilter, JwtAuthenticationEntryPoint authenticationEntryPoint, JWTAccessDeniedHandler accessDeniedHandler) {
        this.jwtFilter = jwtFilter;
        this.authenticationEntryPoint = authenticationEntryPoint;
        this.accessDeniedHandler = accessDeniedHandler;
    }

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

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

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
                .headers().frameOptions().disable().and()
                .csrf().disable()
                .cors().and()
                .authorizeHttpRequests(auth -> {
                    auth.requestMatchers("/api/public", "/h2-console/**", "/api/auth/login", "/api/auth/signup", "/**").permitAll();
                    auth.requestMatchers("/api/v1/admin").hasAuthority("ADMIN");
                    auth.requestMatchers("/api/v1/area").hasAnyAuthority("ADMIN", "USER");
                    auth.anyRequest().authenticated();
                })
                .formLogin().disable()
                .httpBasic().disable()
                .exceptionHandling().accessDeniedHandler(accessDeniedHandler)
                .authenticationEntryPoint(authenticationEntryPoint)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
                .build();
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().requestMatchers
                ("/api/public", "/h2-console/**", "/api/auth/login", "/api/auth/signup", "/**");
    }

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedMethods("*");
            }
        };
    }
}
Enes Birisik
  • 101
  • 4
  • Hi Enes, but sadly and() and disable() are deprecated and auth.requestMatchers("anyApi") is giving me error : This method cannot decide whether these patterns are Spring MVC patterns or not. If this endpoint is a Spring MVC endpoint, please use requestMatchers(MvcRequestMatcher); otherwise, please use requestMatchers(AntPathRequestMatcher). – kindMeetsEvil Aug 18 '23 at 06:39
0

Spring Security is updated. And unfortunately WebSecurityConfigurerAdapter is no longer supported. You can check it here. And this can help you:

import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.DefaultSecurityFilterChain;    
import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {

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

        AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
        http.addFilter(new CustomFilter(authenticationManager));

        http.authorizeHttpRequests((authz) -> authz
                        .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
                        .requestMatchers("/rest/saveTodo*").hasRole("ADMIN")
                        .requestMatchers("/**").denyAll()
                        .requestMatchers(
                                "/**/index*",
                                "/**/logout/",
                                "/**/logoutApp",
                                "/rest/getversion*",
                                "/rest/dologin/*",
                                "/rest/menu*",
                                "/rest/getScript*",
                                "/rest/**").permitAll()
                        .anyRequest().permitAll())
                .formLogin(withDefaults()).exceptionHandling((exceptionHandling) ->
                        exceptionHandling.authenticationEntryPoint(forbiddenEntryPoint()))
                .exceptionHandling((exceptionHandling) ->
                        exceptionHandling.accessDeniedHandler(accessDeniedHandler())) // Use the AccessDeniedHandler bean here
                .and()             
                .csrf().disable()
                .headers().disable();     


}
azizkale
  • 37
  • 2
  • 6
  • 1
    Hi @azizkale, Thank you for the response, I know that spring-security's WebSecurityConfigurerAdapter is deprecated and I need to remove this class, If you see carefully. I have changed the code which I have shown in the actual question also. but it doesn't seems to work also. I will check this and let you know if it is working! – kindMeetsEvil Aug 25 '23 at 07:38
  • it helped me on my case. you can check it: https://www.youtube.com/watch?v=mkdVgx0ylpU – azizkale Aug 28 '23 at 20:47
0

Based on your information that, before migration to 3.1.2 version all work great and SecurityContextHolder.getContext().getAuthentication() didn't return null. The problem is in the newest configuration.

Also according to oldest configuration from 2.6.6, the 3.1.2 configuration should look so:

  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
      http.csrf(AbstractHttpConfigurer::disable);
      http.headers(AbstractHttpConfigurer::disable);
      http.exceptionHandling(handlingConfigurer -> {
              handlingConfigurer.accessDeniedPage(accessDeniedHandler());
              handlingConfigurer.authenticationEntryPoint(forbiddenEntryPoint());
      });
      http.addFilterAt(preAuthFilter(), AbstractPreAuthenticatedProcessingFilter.class);
      http.authorizeHttpRequests(request -> {
         request.requestMatchers("/**/index*",
             "/**/logout/",
             "/**/logoutApp",
             "/rest/getversion*",
             "/rest/dologin/*",
             "/rest/menu*",
             "/rest/getScript*",
             "/rest/**").permitAll();
         request.requestMatchers("/rest/saveTodo*").hasRole("ADMIN");
         request.requestMatchers("/**").denyAll();
          });
      return http.build();
    }

  @Bean
  public WebSecurityCustomizer webSecurityCustomizer() {
    return (web) -> web.ignoring().requestMatchers("/**/*.png*","/**/*.js*","/**/*.jpg*","/**/*.svg*","/**/*.ico*",
            "/**/*.css*","/**/login*","/**/*.woff*","/**/*.ttf*","/**/*.eot*");
  }
Andrei Lisa
  • 1,361
  • 3
  • 11