Spring Security and Oauth2.0

The problem

Recently, due to a change of job, I returned to Java background. My first project is to build a user authentication center, which is where I stepped into the Spring Security pit. One of the most popular solutions is Spring Security + Oauth2.0 + JWT. But when I started integrating Spring Security with Oauth2.0, I suddenly realized that it was not easy. When creating a Springboot project, you can select the following Oauth2.0 dependencies:

spring-boot-starter-oauth2-client
spring-boot-starter-oauth2-resource-server
spring-cloud-starter-oauth2
Copy the code

I wonder why I still rely so much on packages. In line with the principle of baidu programming, from a number of “the world article copy” blog found that they also use another two dependencies:

spring-security-oauth2
spring-security-oauth2-autoconfigure
Copy the code

This is my head big ah, why still whole so complicated. So we’ll have to dig for official documents.

Official Documentation

When he saw the Spring official explanation for Oauth2.0, he said this

The Spring Security OAuth project is deprecated. The latest OAuth 2.0 support is provided by Spring Security. See the OAuth 2.0 Migration Guide for further details.

This means that the original Spring Security OAuth2.0 is deprecated and OAuth2.0 support is now integrated into Spring Security. I’m at a loss… Emmm. This means that most of the methods in spring-security-oauth2 are crossed out (deprecated). Why is that?

Later, I dug into the history of OAuth and The Spring community in the spirit of melon eating. In 2018, the Spring community announced that it was phasing out existing OAuth2 support and building the next generation of OAuth2.0 support in Spring Security5. The cause is Oauth2 landing chaos: Implementations of OAuth2 were provided in Spring Security OAuth, Spring Cloud Security, Spring Boot 1.5.x, and the then latest Spring Security5.x. Therefore, the official must be unified in one place.

I thought, this is a good thing, save people not knowing which one to use. Oauth2.0 support has also been added to OpenID Connect1.0. However, the community has announced that it will no longer support licensing servers. Because authorization servers are officially considered a product form, not a framework, there are already many commercial and open source authorization servers (Keycloak, Okta). But a number of developers disagree ah, in the community heated discussion. So the official compromised and launched a new project, Spring-authorization-Server, which has been iterated to version 0.0.3.

Status Quo & Migration

After the melon, let’s see what the bags are like now.

Spring-security-oauth2 -> is deprecated. It is recommended not to use spring-security-oauth2- > is deprecated. Spring-boot -starter-oauth2-client -> latest spring-boot-starter-oauth2-resource-server -> latest Spring-cloud-starter-oauth2 -> references spring-security-oauth2, but has not yet been deprecatedCopy the code

This makes it clear that the current project needs to reference the corresponding package based on the purpose of the service.

Authorization server

If the service wants to be an authorization server, it can only reference Spring-cloud-starter-oAuth2 for now. Because this package also references Spring-security-OAuth2, but has not been Deprecated and is still configured using the @EnableAuthorityServer annotation. After the Spring-authorization-Server matures, a switch is required.

The client

Now if you want to develop a client, just refer to the spring-boot-starter-oAuth2-client, also need to be in the original SpringSecurity configuration class, call. Oauth2Client () can be configured. The @enableoAuth2Client annotation is no longer required.

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
			.authorizeRequests()
				.anyRequest().authenticated()
				.and()
			.formLogin()
				.loginPage("/login")
				.failureUrl("/login-error")
				.permitAll()
				.and()
			.oauth2Client(); //}}Copy the code

In addition, also need to configure the WebClient and OAuth2AuthorizedClientManager the two beans. How to do that? Dig a hole first and fill it later.

Resource server

The resource server also only needs to refer to spring-boot-starter-oauth2-resource-server. If JWK is used, the configuration is as follows (also just call.oAuth2Resourceserver ()).

@Configuration
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    @Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
    private String jwkSetUri;

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/message/**").hasAuthority("SCOPE_all")
                .anyRequest().authenticated();
    }

    @Bean
    JwtDecoder jwtDecoder(a) {
        return NimbusJwtDecoder.withJwkSetUri(this.jwkSetUri).build(); }}Copy the code

That’s a lot more refreshing. For details about Migration, see the official OAuth 2.0 Migration Guide.