Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Migration guide for Spring security 5

I have multi-module maven project Spring boot 2.3.1.RELEASE, there I use spring security over OAuth 2.0. One of my modules contains configuration for security:

Authorization server config

@Configuration
@EnableAuthorizationServer //deprecated
public class AuthorizationServerOAuth2Config extends AuthorizationServerConfigurerAdapter { //deprecated

    private static final String SINGING_KEY = "";
    private static final String CLIENT_ID = "";
    private static final String CLIENT_SECRET = "";
    private static final String[] AUTHORIZED_GRANT_TYPES = {"password", "refresh_token"};
    private static final String[] SCOPES = {"read", "write"};

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) { //deprecated
        security
                .tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { //deprecated

        clients.inMemory()
                .withClient(CLIENT_ID)
                .secret(passwordEncoder.encode(CLIENT_SECRET))
                .authorizedGrantTypes(AUTHORIZED_GRANT_TYPES)
                .scopes(SCOPES)
                .accessTokenValiditySeconds(1800)
                .refreshTokenValiditySeconds(9600);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) { //deprecated

        endpoints
                .tokenStore(tokenStore())
                .authenticationManager(authenticationManager)
                .accessTokenConverter(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() { //deprecated
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey(SINGING_KEY);
        return converter;
    }

    @Bean
    public TokenStore tokenStore() { //deprecated
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() { //deprecated
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }
}

Resource server config

@Configuration
@EnableResourceServer //deprecated
public class ResourceServerOAuth2Config extends ResourceServerConfigurerAdapter { //deprecated
}

pom.xml


<?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">
    <parent>
        <groupId>com.skill.improvement</groupId>
        <artifactId>app</artifactId>
        <version>1.0.1-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>security</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <!-- 2.3.1.RELEASE -->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!-- 2.3.1.RELEASE -->
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>2.3.1.RELEASE</version>
        </dependency>
    </dependencies>
</project>

Main security config


@Order(1)
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String ADMIN_PASSWORD = "";
    private static final String USER_PASSWORD = "";

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .httpBasic().disable()
                .csrf().disable()
                .anonymous().disable()
                .authorizeRequests()
                .antMatchers("/v1/**").authenticated()
                .and().exceptionHandling().authenticationEntryPoint(new JwtAuthenticationEntryPoint())
                .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler()) //deprecated
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring()
                .antMatchers(
                "/v2/api-docs",
                "/configuration/ui",
                "/swagger-resources/**",
                "/configuration/security",
                "/swagger-ui.html",
                "/webjars/**")
        .antMatchers(HttpMethod.GET, "/v1/**")
        .antMatchers(HttpMethod.PATCH, "/v1/**");
    }

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(inMemoryUserDetailsManager());
    }

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

    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager() {

        return new InMemoryUserDetailsManager(getDefaultUsers());
    }

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

    @Bean
    public OncePerRequestFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter();
    }

    private List<UserDetails> getDefaultUsers() {

        List<UserDetails> userDetailsList = new ArrayList<>();
        userDetailsList.add(User.withUsername("admin").password(passwordEncoder().encode(ADMIN_PASSWORD))
                .roles("ADMIN").build());
        userDetailsList.add(User.withUsername("user").password(passwordEncoder().encode(USER_PASSWORD))
                .roles("USER").build());
        return userDetailsList;
    }
}

Everything works fine, but almost everything is deprecated since Spring Security 5.2.x. I read this guide

but I am not sure how to successfully finish the migration. Is there any understandable guide on how to do it?

like image 835
Peter S. Avatar asked Jul 21 '20 09:07

Peter S.


People also ask

Is OAuth2RestTemplate deprecated?

RELEASE classes such as OAuth2RestTemplate , OAuth2ProtectedResourceDetails and ClientCredentialsAccessTokenProvider have all been marked as deprecated.

What is new spring Security 5?

Spring Security 5.0 provides a number of new features as well as support for Spring Framework 5. In total there were 400+ enhancements and bugs resolved. You can find the change log at 5.0.

What is spring authorization server?

Spring Authorization Server is a framework that provides implementations of the OAuth 2.1 and OpenID Connect 1.0 specifications and other related specifications.

What is Spring Security oauth2?

It serves as an open authorization protocol for enabling a third party application to get limited access to an HTTP service on behalf of the resource owner. It can do so while not revealing the identity or the long-term credentials of the user. A third-party application itself can also use it on its behalf.


1 Answers

In spring security's current release they have not given support of authorization server. They are working on authorization server support but the project is under experimental mode. Besides spring security team already integrated resource server as well as Oauth2 client support in spring security 5 as single spring security project. Until, they don't release the support of latest spring's authorization server you can use your old authorization server but you won't be able to keep your resource server auth server because latest resource server and client configuration comes in different dependency and the configurations will conflict with old oauth2 support .

I would recommend you to use any other authorization server meanwhile they release spring's latest auth server. I would suggest you to use keyclock auth server that I am personally using.

See this

like image 114
Amit Mishra Avatar answered Oct 20 '22 16:10

Amit Mishra