Search code examples
javaspring-bootspring-securityspring-oauth2

Migrate Spring Security configuration to Spring Cloud 2022.0.4


I want to migrate this Spring security configuration to latest Spring Cloud:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

public class DefaultSecurityConfig extends ResourceServerConfigurerAdapter {

  @Autowired
  private ResourceServerProperties resource;

  @Autowired
  private CustomUserDataAuthenticationConverter customUserDataAuthenticationConverter;

  public DefaultSecurityConfig() {
  }

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

    http.authorizeRequests()
        .antMatchers("/configuration/**",)
        .permitAll();

    http.authorizeRequests().antMatchers("/**").authenticated();

    final OAuth2AuthenticationEntryPoint oAuth2AuthenticationEntryPoint =
        new CustomOAuth2AuthenticationEntryPoint();

    http.exceptionHandling().authenticationEntryPoint(oAuth2AuthenticationEntryPoint);
  }

  @Override
  public void configure(final ResourceServerSecurityConfigurer resources) {
    resources.tokenServices(tokenServices());
    resources.resourceId(resource.getResourceId());
  }

  private TokenStore customTokenStore() {
    return new JwtTokenStore(accessTokenConverter());
  }

  private JwtAccessTokenConverter accessTokenConverter() {
    JwtAccessTokenConverter converter = new NonValidatingAccessTokenConverter();
    converter.setAccessTokenConverter(customAccessTokenConverter());
    return converter;
  }

  private DefaultTokenServices tokenServices() {
    DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
    defaultTokenServices.setTokenStore(customTokenStore());
    return defaultTokenServices;
  }

  private DefaultAccessTokenConverter customAccessTokenConverter() {
    DefaultAccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
    tokenConverter.setUserTokenConverter(customUserDataAuthenticationConverter);
    return tokenConverter;
  }
}

As you can see I migrate parts of the code but several issues are not clear:

  1. implementation 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure' Is removed from spring.dependency.management package. What package should replace it?

  2. ResourceServerConfigurerAdapter is deprecated. How to replace it?

  3. OAuth2AuthenticationEntryPoint is deprecated. How to replace it?

What should be the proper way to migrate the code accordingly?


Solution

  • How in official documentation was descried that spring-security-oauth-reaches-end-of-life

    And also how we discussed in comments, you will have an authorization-server Keycloak as Identity Provider with oAuth2.0 and Oidc connect.

    Your migration code will have next steps:

    Replace current one with Resource-server in your case with JWT as Bearer Token

    Gradle/Maven configuration:

    Gradle:

      implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: '3.1.2'
    
      implementation group: 'org.springframework.boot', name: 'spring-boot-starter-oauth2-resource-server', version: '3.1.2'
    

    Maven:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
        <version>3.1.2</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        <version>3.1.2</version>
    </dependency>
    

    In application.yml file you should provide next ones paths:

    spring:
      security:
        oauth2:
          resourceserver:
            jwt:
              issuer-uri: 
              jwk-set-uri: 
    

    This values you will find out to : /.well-known/openid-configuration path on Keycloak side.

    Where you security config layer will look so:

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {
    
         
      @Bean
      public AuthenticationManager authenticationManager(
          AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
      }
    
      @Bean
      public SecurityFilterChain securityFilterChain(HttpSecurity request) throws Exception {
    
        request.cors(corsConfigurer -> corsConfigurer.configurationSource(yourCustomCorsConfiguration))
            .csrf(AbstractHttpConfigurer::disable);
    
        request.headers(http -> http.frameOptions(FrameOptionsConfig::sameOrigin));
        request.sessionManagement(sessionAuthenticationStrategy ->
            sessionAuthenticationStrategy.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
    
        request.authorizeHttpRequests(requestMatcherRegistry -> {
    
          requestMatcherRegistry.anyRequest().authenticated();
        });
    
        request.oauth2ResourceServer(httpSecurityOAuth2ResourceServerConfigurer ->
                httpSecurityOAuth2ResourceServerConfigurer.jwt(
                    token -> token.jwtAuthenticationConverter(myConverter())));
    
        return request.build();
      }
    
    @Bean
    public JwtDecoder jwtDecoder() {
        return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
    }
    
    }
    

    And also you should to have a look to oauth2-client, spring-authorization-server