OAuth 2.0 Deep Dive: A Guide to Tokens, Flows & Delegate Access with Spring Security

Share this

If you’re building secure APIs, SPAs, or mobile apps, understanding the underlying standards — like OAuth 2.0, OpenID Connect, and SAML — is critical.
Note: This article belongs to Part 2.1: Security Standards in our Application Security series.

In this post, we’ll explore OAuth 2.0, the most widely adopted authorization framework in the modern web. We’ll break down:

  • What OAuth 2.0 is and why it exists
  • The key flows developers need to know
  • Token types and how they work
  • How OAuth enables delegated access securely
  • Spring Security examples to bring it all together

What Is OAuth 2.0?

OAuth 2.0 is an authorization framework – a security standard you can say. It allows a third-party application to obtain limited access to user resources on another service — without handling the user’s credentials directly.

Think:

“I want to let a calendar app access my Google Calendar — without giving it my Google password.”

It’s based on token issuance and scoped access, and it separates resource owners (users), clients (apps), authorization servers, and resource servers.

Why Not Just Use Login + Roles?

Because modern systems are:

  • Distributed (microservices, APIs)
  • Multi-client (SPAs, mobile apps, CLI)
  • Often integrating third-party access
  • Needing secure delegation without trust violation

OAuth solves all this by issuing time-limited, scoped access tokens on behalf of users or systems.

The Core OAuth Roles

RoleDescription
Resource OwnerThe end user or entity who owns the data
ClientThe application requesting access to the resource
Authorization ServerThe system issuing tokens (e.g., Google, Okta, Auth0)
Resource ServerThe API or service being accessed (e.g., your backend)

Key OAuth 2.0 Flows

Different flows exist depending on client type, trust level, and user interaction:

1. Authorization Code Flow (With PKCE)

Use Case: Web apps, SPAs, mobile apps

  • Redirect-based
  • Uses temporary authorization code, exchanged for token
  • PKCE secures public clients
Browser → Login Page → Redirect with Code → Backend exchanges code for token

Recommended for most interactive apps

2. Client Credentials Flow

Use Case: Machine-to-machine communication

  • No user involved
  • Auth server issues token to the client based on client ID + secret

✅ Best for backend services calling other services

3. Refresh Token Flow

Use Case: Token renewal

  • Long-lived refresh token used to obtain new access tokens
  • Used in combination with Authorization Code flow

4. Device Code Flow

Use Case: CLI apps, smart TVs

  • User logs in on a separate device
  • Client polls token endpoint

Token Types Explained

🔑 Access Token

  • Used to access protected resources
  • Usually a JWT or opaque string
  • Carries scopes, user ID, roles

🔄 Refresh Token

  • Used to obtain a new access token without re-authenticating the user
  • Must be stored securely — usually never exposed to browsers

🪪 ID Token (from OpenID Connect)

  • Contains user identity (e.g., name, email, sub)
  • Meant for client-side identity info, not for API access

✅ Spring Security: OAuth2 Client (Login)

To support OAuth login (Authorization Code Flow with PKCE):

@Configuration
@EnableWebSecurity
public class OAuth2LoginConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.oauth2Login() // Enables OAuth2 login with external IdP
.and()
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
);

return http.build();
}
}

Spring will handle redirects, token exchange, and user session creation via SecurityContext.

✅ Spring Security: OAuth2 Resource Server (API)

To secure a REST API that receives access tokens:

@Configuration
public class ResourceServerConfig {

@Bean
public SecurityFilterChain apiSecurity(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/admin/**").hasAuthority("SCOPE_admin")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2
.jwt() // Validates incoming JWTs
);

return http.build();
}
}

Spring will decode JWTs automatically, validate their signature, expiry, issuer, and audience.

🔐 Real-World Delegated Access

Let’s say you’re building a service that posts on behalf of a user to Twitter.

Without OAuth:

  • You’d need to ask for the user’s password. Bad idea.

With OAuth:

  • The user authenticates with Twitter, and you get an access token scoped to write:posts
  • You never see their password — and Twitter can revoke your token at any time

That’s delegated access done right.

Common Pitfalls

  • ❌ Using id_token as an access token (they serve different purposes!)
  • ❌ Forgetting to validate scopes before granting access
  • ❌ Storing refresh tokens insecurely (never store in browser localStorage)
  • ❌ Not rotating signing keys for JWTs (use JWKs + key rotation policies)

Best Practices for Developers

  • Use Authorization Code flow with PKCE for SPAs and mobile apps
  • Always validate access tokens on the resource server
  • Use short-lived access tokens + refresh tokens
  • Validate token claims (issuer, audience, scope, expiry)
  • Never rely on frontend-only logic for authorization

Conclusion

OAuth 2.0 is the industry standard for secure, scalable, and flexible authorization. Whether you’re securing APIs, building user login flows, or enabling third-party access to data, OAuth provides the tools to do it safely — without compromising user trust.

Spring Security offers excellent support for both OAuth clients and resource servers, making it easy to integrate secure token-based workflows into your applications.

Check out https://spring.io/projects/spring-security and https://en.wikipedia.org/wiki/Spring_Security Wikipedia links for more information on the current topic.

What’s Next

Up Next in our Application Security Series is:
Part 2.2 👉 OpenID Connect in Spring Security: Login, ID Tokens & Best Practices

We’ll dive into OpenID Connect: Turning OAuth into a Login System

  • How OIDC builds on OAuth2
  • How to use id_token safely
  • Adding OIDC login to your Spring Boot app

Have a Question?

OAuth can be confusing at first — especially with all the flows and tokens involved. If you’re working through a real implementation or unsure how to apply it to your project, drop a comment or send a message. Happy to help!

Share this

Leave a comment

Your email address will not be published. Required fields are marked *