Information Security 7 min read

Build an OAuth2 Authorization Server with Spring Authorization Server 0.2.0

This tutorial walks through setting up Spring Authorization Server 0.2.0 on Spring Boot 2.5.3, covering required dependencies, security configuration, SAS server setup, testing the authorization code flow, token exchange, refresh, and revocation, with complete code snippets and curl commands.

Java Architecture Diary
Java Architecture Diary
Java Architecture Diary
Build an OAuth2 Authorization Server with Spring Authorization Server 0.2.0

Background

Spring Authorization Server (SAS) is the Spring team's latest OAuth‑compatible authorization server project, intended to replace the original Spring Security OAuth Server.

After six months of development, version 0.2.0 has been released, supporting authorization code, client, refresh, revocation and other OAuth features.

The SAS project has moved to the official repository and is now an official sub‑project.

The author's earlier article is no longer compatible with the current version, so this guide consolidates the setup steps.

Environment: Spring Boot 2.5.3 && SAS 0.2.0.

Getting Started

1. Core Dependencies

Include SAS and Spring Security dependencies (see comments in the pom snippet).

<code>&lt;!-- Note: the official repository does not have the 'experimental' groupId; be careful or the jar cannot be downloaded --&gt;
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-oauth2-authorization-server</artifactId>
  <version>0.2.0</version>
</dependency>

&lt;!-- Provide form authentication --&gt;
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>
</code>

2. Configure Spring Security

Define the user source and form‑login details.

<code>@EnableWebSecurity
public class DefaultSecurityConfig {
    @Bean
    UserDetailsService users() {
        UserDetails user = User.builder()
                .username("lengleng")
                .password("{noop}123456")
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }
    @Bean
    SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests(authorizeRequests ->
                authorizeRequests.anyRequest().authenticated()
        ).formLogin(withDefaults());
        return http.build();
    }
}
</code>

3. Configure SAS Server

<code>@Configuration
@EnableWebSecurity
public class AuthServerConfiguration {
    // security mounts SAS – the most important step
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
        return http.formLogin(Customizer.withDefaults()).build();
    }

    // client registration
    @Bean
    public RegisteredClientRepository registeredClientRepository() {
        RegisteredClient client = RegisteredClient.withId("pig")
                .clientId("pig")
                .clientSecret("{noop}pig")
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                .authorizationGrantTypes(authorizationGrantTypes -> {
                    authorizationGrantTypes.add(AuthorizationGrantType.AUTHORIZATION_CODE);
                    authorizationGrantTypes.add(AuthorizationGrantType.REFRESH_TOKEN);
                })
                .redirectUri("https://pig4cloud.com")
                .build();
        return new InMemoryRegisteredClientRepository(client);
    }

    // beans for JWT generation (see source for details)
    @Bean
    @SneakyThrows
    public JWKSource<SecurityContext> jwkSource() {
        // ...
    }

    @Bean
    public static JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
        // ...
    }
}
</code>

Test Run

With the above configuration the SAS server is ready. The following steps test the authorization‑code flow.

Open the browser and navigate to:

<code>http://localhost:3000/oauth2/authorize?client_id=pig&client_secret=pig&response_type=code&redirect_uri=https://pig4cloud.com</code>

After logging in, the server redirects back with an authorization code.

Exchange the code for a token:

<code>curl --location --request POST 'http://localhost:3000/oauth2/token' \
  --header 'Authorization: Basic cGlnOnBpZw==' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode 'code=YOUR_AUTH_CODE' \
  --data-urlencode 'redirect_uri=https://pig4cloud.com'</code>

Refresh the token:

<code>curl --location --request POST 'http://localhost:3000/oauth2/token' \
  --header 'Authorization: Basic cGlnOnBpZw==' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=refresh_token' \
  --data-urlencode 'refresh_token=YOUR_REFRESH_TOKEN' \
  --data-urlencode 'redirect_uri=https://pig4cloud.com'</code>

Revoke Tokens

Revoke using an access token:

<code>curl --location --request POST 'http://localhost:3000/oauth2/revoke' \
  --header 'Authorization: Basic cGlnOnBpZw==' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'token=ACCESS_TOKEN' \
  --data-urlencode 'token_type_hint=access_token'</code>

Revoke using a refresh token:

<code>curl --location --request POST 'http://localhost:3000/oauth2/revoke' \
  --header 'Authorization: Basic cGlnOnBpZw==' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'token=REFRESH_TOKEN' \
  --data-urlencode 'token_type_hint=refresh_token'</code>

Next Preview

SAS implements OAuth 2.1 and does not support the password grant type. The next article will show how to extend SAS to add password‑grant support. Stay tuned.

Source code: https://github.com/lltx/auth-server-demo

JavaSpringSpring BootsecurityOAuth2authorization-server
Java Architecture Diary
Written by

Java Architecture Diary

Committed to sharing original, high‑quality technical articles; no fluff or promotional content.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.