On this page
OAuth 2.0 Overview
OAuth 2.0 is an authorization framework that allows third-party applications to access user resources without exposing credentials. It defines roles, flows, and token types used across modern Java applications.
Roles
| Role | Description |
|---|---|
| Resource Owner | The user |
| Client | Application requesting access |
| Authorization Server | Issues tokens |
| Resource Server | Hosts protected resources (API) |
Token Types
| Token | Purpose | Lifetime |
|---|---|---|
| Access Token | API authorization | Short (minutes–hours) |
| Refresh Token | Obtain new access tokens | Long (days–weeks) |
| ID Token (OIDC) | User identity claims | Short |
Authorization Flows
Authorization Code (recommended for web apps)
1. Client redirects user to Authorization Server
2. User authenticates and grants consent
3. Server redirects back with authorization code
4. Client exchanges code for access token (server-side)
5. Client calls Resource Server with access token
Client Credentials (service-to-service)
1. Client sends client_id + client_secret to token endpoint
2. Authorization Server returns access token
3. Client calls Resource Server
No user involved — for machine-to-machine communication.
PKCE (for SPAs and mobile)
Extension of Authorization Code flow preventing code interception:
1. Client generates code_verifier + code_challenge
2. Sends code_challenge with authorization request
3. Exchanges code + code_verifier for token
Spring Authorization Server
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
</dependency>
@Bean
public RegisteredClient registeredClient() {
return RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("my-client")
.clientSecret("{bcrypt}$2a$10$...")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.redirectUri("http://localhost:8080/login/oauth2/code/my-client")
.scope("read")
.scope("write")
.build();
}
Token Endpoint Request
curl -X POST https://auth.example.com/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=my-service" \
-d "client_secret=secret" \
-d "scope=read write"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read write"
}
Scopes
Scopes limit what a token can access:
read:users — read user data
write:orders — create/update orders
admin — full access
Resource servers validate scopes before granting access.
Best Practices
- Use Authorization Code + PKCE for all user-facing clients
- Use Client Credentials for service-to-service communication
- Keep access tokens short-lived; use refresh tokens for renewal
- Never expose client secrets in frontend code
- Validate token audience (
aud) and issuer (iss) on resource servers - Use established providers (Keycloak, Auth0) rather than building from scratch