An authorization server issues access tokens that let a client call a protected API. Think of a token as a valet key: it grants limited access without handing the client the user’s password. The authorization server is separate from both the client and the application providing the API. section 8.0 section 8.2
In the authorization code flow, the client sends the user’s browser to the authorization server for login and consent. After the user grants permission, the server redirects back with an authorization code. The client exchanges that code for an access token, then sends the token with API requests. A token can expire or be revoked without changing the user’s password. section 8.1 section 8.4
A Spring Boot implementation has a few distinct pieces:
- Create a separate application with web and security support. Configure form-based login and a user lookup so people can authenticate. section 8.2
- Register each client with credentials, permitted grant types, a redirect URI, requested scopes, and a consent requirement. These settings define how that client may request access. section 8.2
- Configure signing keys. In this setup, the server signs JWT access tokens, and the API obtains the matching public key from the server’s JWK set endpoint to verify them. section 8.2 section 8.3
@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);
}
The registered-client configuration shows the client ID and secret, authorization code and refresh-token grants, redirect URI, ingredient-management scopes, and required user consent. section 8.2
Granting ingredient-management access
An administrator approves a client’s request for writeIngredients and deleteIngredients. The client sends its authorization code, redirect URI, and client credentials to /oauth2/token. The response contains a Bearer access token, a refresh token, the granted scopes, and an expiration interval. The client can then send the access token in an Authorization header when adding an ingredient. section 8.2 section 8.3
Issuing a token is only half the setup. The API acts as a resource server: it checks the token’s signature and requires the appropriate scope for protected endpoints. The client must request the scopes it needs and pass its token along with each protected request. In this example, Spring Authorization Server is experimental and supports authorization code and client credentials grants, rather than every OAuth 2 grant type. section 8.2 section 8.3 section 8.4





