JWT & OAuth2
OAuth2 — Authorization Code Flow Explained Simply
Understanding client, authorization server, and user roles interactions.
Introduction
OAuth 2.0 is an industry-standard delegation framework (RFC 6749) that allows applications to obtain limited access to user accounts on an HTTP service (e.g., Google or Okta) without sharing the user's password. The Authorization Code Flow is the most secure flow, utilizing a server-to-server exchange channel to distribute access tokens safely.
Why It Matters
Directly sharing credentials with third-party apps compromises account security. OAuth2 isolates user credentials by delegating authentication to an external Identity Provider (IdP). The IdP validates the user and hands a specific Access Token to the client application. The client can only read resources that match its granted permissions (Scopes).
Real-World Analogy
Think of OAuth2 like valet parking keys. Instead of giving the valet parking attendant your primary house/car master key (which would let them open the glovebox, trunk, and drive anywhere), you hand them a specialized valet key. The valet key only starts the engine and only drives a short distance.
Detailed Mechanics
1. Core Protocol Roles
- Resource Owner (User): The entity who owns the account and grants access.
- Client: The application (e.g. React frontend or Spring backend) requesting access.
- Authorization Server: The server that authenticates the user and issues authorization codes and tokens (e.g. Okta, Keycloak).
- Resource Server: The API hosting protected user data (e.g. Google Calendar API).
2. Step-by-Step Authorization Flow
- Redirect to IdP: The client directs the browser to the authorization endpoint:
https://auth-server.com/authorize?response_type=code&client_id=myClient&redirect_uri=myAppRedirect&scope=read. - Consent Approval: The user logs in at the IdP and consents to sharing the requested scopes.
- Auth Code Return: The IdP redirects the browser back to the client redirect URI, passing a temporary
codequery parameter in the URL. - Token Exchange: The client's backend makes a POST request to the token endpoint containing the
codeand its privateclient_secret. - Tokens Issued: The authorization server validates the code and secret, then returns an
access_token(and optionalid_token/refresh_token).
3. Proof Key for Code Exchange (PKCE)
For public clients (like single-page applications or mobile apps) that cannot store a client secret safely, the PKCE extension is mandatory. The client generates a random Code Verifier and sends its hashed value (Code Challenge) during Step 1. In Step 4, it sends the plain verifier, allowing the auth server to cryptographically confirm that the client requesting the token is the exact same one that initiated the flow.
Practical Example
The sequence below maps the OAuth2 redirect exchange flow:
| Sender | Receiver | Parameters / Request Details |
|---|---|---|
| Browser (Redirect) | Auth Server (/authorize) | client_id, redirect_uri, response_type=code, scope |
| Auth Server (Redirect) | Browser (Redirect URI) | code=XYZ12345, state=randomStateString |
| Client Backend (POST) | Auth Server (/token) | grant_type=authorization_code, code=XYZ12345, client_id, client_secret |
Quick Quiz
Q1: Why is the temporary Authorization Code sent to the browser first instead of returning the Access Token directly in Step 3?
A) Browser connections are too slow to receive tokens directly.
B) The browser channel is exposed (history logs, address bar). Sending the code first allows exchanging it for the access token over a secure, backend-to-backend channel using the client secret.
C) Google charges a transaction fee for issuing tokens in URLs.
D) The Authorization Code is used to load custom page styles.
Answer: B — Backend backchannels are secure from browser inspection, shielding the final access token from interception.
Q2: When is the PKCE (Proof Key for Code Exchange) extension required for OAuth2 implementation?
A) Only for desktop Java applications.
B) When the client application is stateless and cannot verify JWTs.
C) When implementing authentication for public clients (like React SPAs or Mobile Apps) that cannot securely hide their client secret.
D) It is only required for local offline testing.
Answer: C — PKCE replaces client secrets with dynamically generated cryptographic challenge verifiers, preventing intercept bypasses in public environments.
Scenario-Based Challenge
Production Scenario:
You configure OAuth2 login for a Spring Boot dashboard. Users can authenticate successfully, but when they refresh their dashboard page, they are logged out. The session is not persisting across page refreshes. What is the most likely cause?
View Solution
This happens when the Spring Boot dashboard has been configured statelessly (e.g. SessionCreationPolicy.STATELESS is active, or the security context repository is not configured to save state) but does not store access tokens locally.
To resolve this:
- For standard server-side MVC dashboards, ensure
SessionCreationPolicy.ALWAYSorIF_REQUIREDis active so Spring Security stores user context inside theHttpSession. - Verify cookie settings: ensure cookies are not being blocked by the browser due to mismatched domain names or lack of HTTPS parameters.
Interview Questions
1. Conceptual: What is the difference between OAuth 2.0 and OpenID Connect (OIDC)?
OAuth 2.0 is an **authorization** framework for delegating API access (it issues access tokens to read calendars, profile pictures, etc.). OpenID Connect is an identity extension layer built directly on top of OAuth 2.0 that introduces the **ID Token** (always a JWT) containing user identity metadata to perform **authentication**.
2. Concept: What is the purpose of the 'state' parameter in the OAuth2 authorization redirect query?
The state parameter is a random string generated by the client and sent to the auth server. The auth server returns it unmodified in the redirect query. The client matches the returned state against the original value to prevent **Cross-Site Request Forgery (CSRF)** login attacks.
Production Considerations
Enforce strict whitelist mappings for redirect URIs at the Identity Provider to block authorization code redirect hijackings. Use short-lived authorization codes (typically valid for 1 minute) and set single-use restrictions to prevent reuse attacks.