Vy Do
Vy Do

Reputation: 52556

Updating to Spring Security 6.0 - replacing Removed and Deprecated functionality for securing requests

I'm trying to upgrade to Spring Boot 3.0.0 and Spring Security 6.0.

I've found that method for securing requests authorizeRequests() has been deprecated. And also method antMatchers() and @EnableGlobalMethodSecurity annotation has removed. How can I upgrade my security configuration?

My code:

package org.sid.securityservice.config;

import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
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.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtEncoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
    private RsakeysConfig rsakeysConfig;
    private PasswordEncoder passwordEncoder;

    public SecurityConfig(RsakeysConfig rsakeysConfig, PasswordEncoder passwordEncoder) {
        this.rsakeysConfig = rsakeysConfig;
        this.passwordEncoder = passwordEncoder;
    }

    //@Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
    @Bean
    public AuthenticationManager authenticationManager(UserDetailsService userDetailsService){
        var authProvider = new DaoAuthenticationProvider();
        authProvider.setPasswordEncoder(passwordEncoder);
        authProvider.setUserDetailsService(userDetailsService);
        return new ProviderManager(authProvider);
    }

    @Bean
    public UserDetailsService inMemoryUserDetailsManager(){
        return new InMemoryUserDetailsManager(
                User.withUsername("user1").password(passwordEncoder.encode("1234")).authorities("USER").build(),
                User.withUsername("user2").password(passwordEncoder.encode("1234")).authorities("USER").build(),
                User.withUsername("admin").password(passwordEncoder.encode("1234")).authorities("USER","ADMIN").build()
        );
    }
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                .csrf(csrf->csrf.disable())
                .authorizeRequests(auth->auth.antMatchers("/token/**").permitAll())
                .authorizeRequests(auth->auth.anyRequest().authenticated())
                .sessionManagement(sess->sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
                .httpBasic(Customizer.withDefaults())
                .build();
    }
    @Bean
    JwtDecoder jwtDecoder(){
        return NimbusJwtDecoder.withPublicKey(rsakeysConfig.publicKey()).build();
    }
    @Bean
    JwtEncoder jwtEncoder(){
        JWK jwk= new RSAKey.Builder(rsakeysConfig.publicKey()).privateKey(rsakeysConfig.privateKey()).build();
        JWKSource<SecurityContext> jwkSource= new ImmutableJWKSet<>(new JWKSet(jwk));
        return new NimbusJwtEncoder(jwkSource);
    }

}

Here's what IDE shows me (struck out authorizeRequests() and missing antMatchers() highlighted in red):

enter image description here

Upvotes: 93

Views: 184417

Answers (4)

Nikhil Choudhary
Nikhil Choudhary

Reputation: 11

To disable csrf in any case for spring security above 6.0, you can also use it like this

@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .requestMatchers("").authenticated()
            .anyRequest().permitAll()
            .and()
            .httpBasic(Customizer.withDefaults())
            .csrf(csrf -> csrf.disable()); **//this is basic and functional**
    return http.build();
}

Upvotes: 1

Mike En
Mike En

Reputation: 171

In case anyone has any problems with the depreciation of jwt in the spring security 6

oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)

The following worked for me

oauth2ResourceServer(spec -> spec.jwt(Customizer.withDefaults()))

Upvotes: 5

Sanjit Shrestha
Sanjit Shrestha

Reputation: 101

'csrf()' is deprecated since version 6.1 and marked for removal solutions:

@Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        contentSecurityConfig(http);
        AntPathRequestMatcher[] requestMatchers = getAntPathRequestMatchers();
        http.authorizeHttpRequests(authorize -> authorize
                        .requestMatchers(requestMatchers).permitAll()
                        .anyRequest().authenticated())
                .oauth2ResourceServer(oauth2 -> oauth2
                        .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter()))
                ).csrf(AbstractHttpConfigurer::disable)
                .httpBasic(withDefaults());
        return http.build();
    }

Upvotes: 6

Alexander Ivanchenko
Alexander Ivanchenko

Reputation: 28988

In Spring Security 6.0, antMatchers() as well as other configuration methods for securing requests (namely mvcMatchers() and regexMatchers()) have been removed from the API.

An overloaded method requestMatchers() was introduced as a uniform mean for securing requests. The flavors of requestMatchers() facilitate all the ways of restricting requests that were supported by the removed methods.

Also, method authorizeRequests() has been deprecated and shouldn't be used anymore. A recommended replacement - authorizeHttpRequests() (you can find more information regarding these changes here).

That's how your SecurityFilterChain might be defined in Spring Security 6.0:

public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
    return httpSecurity
        .csrf(csrf -> csrf.disable())
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/token/**").permitAll()
            .anyRequest().authenticated()
        )
        .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
        .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
        .httpBasic(Customizer.withDefaults())
        .build();
}

Regarding deprecated annotation @EnableGlobalMethodSecurity it was replaced with @EnableMethodSecurity. The rationale behind this change is that with @EnableMethodSecurity property prePostEnabled needed to enable use of @PreAuthorize/@PostAuthorize and @PreFilter/@PostFilter is by default set to true.

So you no longer need to write prePostEnabled = true, just annotating your configuration class with @EnableMethodSecurity would be enough.

Upvotes: 196

Related Questions