Spring Authorization Server provides components for building an OAuth 2 authorization server: an application that issues access tokens to clients. It runs separately from both the client and the API it protects. In the Taco Cloud example, the authorization server issues a token that a client can present when calling the ingredients API. section 8.2 section 8.5
A small Spring Boot authorization server starts with these pieces:
- Create a separate project with the web and security starters. Add JPA and H2 if users will be stored in a relational database. section 8.2
- Add the Spring Authorization Server dependency manually; it is not available from Initializr in this setup. Use a distinct port, such as 9000, to avoid a conflict with the API. section 8.2
- Configure Spring Security for authenticated requests and form-based login. Supply a UserDetailsService that looks up users by username. section 8.2
- Apply the authorization server’s default security configuration in a high-priority SecurityFilterChain. section 8.2
@Configuration(proxyBeanMethods = false)
public class AuthorizationServerConfig {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration
.applyDefaultSecurity(http);
return http
.formLogin(Customizer.withDefaults())
.build();
}
...
}
The authorization server’s security filter chain applies its default configuration and enables form login. section 8.2
The server also needs to know which clients may request tokens. A RegisteredClientRepository can hold a client’s ID, encoded secret, authentication method, grant types, redirect URI, and scopes. The example uses an in-memory repository, enables the authorization-code and refresh-token grants for one client, and requires user consent. A JWKSource supplies an RSA key for the server’s token configuration. section 8.2
@Bean
public RegisteredClientRepository registeredClientRepository(
PasswordEncoder passwordEncoder) {
RegisteredClient registeredClient =
RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("taco-admin-client")
.clientSecret(passwordEncoder.encode("secret"))
.clientAuthenticationMethod(
ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.redirectUri(
"http://127.0.0.1:9090/login/oauth2/code/taco-admin-client")
.scope("writeIngredients")
.scope("deleteIngredients")
.scope(OidcScopes.OPENID)
.clientSettings(
clientSettings -> clientSettings.requireUserConsent(true))
.build();
return new InMemoryRegisteredClientRepository(registeredClient);
}
This registered client connects the authorization-code flow to a specific redirect URI and the permissions requested for the ingredients API. section 8.2
Using the issued token
After login and consent, the client exchanges an authorization code at the server’s /oauth2/token endpoint. The response includes a bearer access token, a refresh token, scopes, and an expiration time. Present the access token in an Authorization: Bearer header when posting an ingredient to the API; the resource server checks the token and required scope. section 8.2 section 8.5
This setup uses the experimental Spring Authorization Server release shown in the dependency example. That release supports authorization-code and client-credentials grants, but not every OAuth 2 grant type. section 8.2


