Introduction to OAuth2 & OpenID Connect
Introduction to OAuth2 & OpenID Connect
The JWT skills you have built so far are powerful — but they only cover one half of a modern security architecture: custom authentication you own end-to-end. In the real world, your service often needs to let users log in with Google or GitHub, or grant a mobile app limited access to your API without sharing a password. That is the problem OAuth 2.0 and OpenID Connect (OIDC) were designed to solve.
Why OAuth2 Exists — The Delegation Problem
Imagine a user wants to give a photo-printing service access to their Google Photos without handing over their Google password. Before OAuth, this was routinely "solved" by giving the third-party app the user's credentials — a practice that is both dangerous and impossible to revoke selectively.
OAuth 2.0 (RFC 6749, 2012) introduces a delegated authorization framework. The user authorises a third-party application to act on their behalf, but the application never learns the user's password. Instead it receives a scoped, time-limited access token. The user can revoke that token at any time without changing their password.
The Four Core Roles
- Resource Owner — the end user (or system) that owns the protected data.
- Client — the application requesting access (e.g., your Spring Boot service, a mobile app, an SPA).
- Authorization Server — the server that authenticates the resource owner and issues tokens (e.g., Keycloak, Auth0, Okta, Google).
- Resource Server — the API that holds the protected resources and validates tokens before serving them. In the next lesson, your Spring Boot app is the resource server.
Grant Types — How a Client Obtains a Token
A grant type defines the protocol flow a client uses to obtain an access token. OAuth 2.0 defines several; you need to know four.
1. Authorization Code Grant (+ PKCE)
This is the safest and most commonly used grant for applications that have a server-side component or a browser-based frontend. The flow:
- The client redirects the user's browser to the authorization server, supplying
response_type=code,client_id,redirect_uri, andscope. - The user authenticates and consents at the authorization server.
- The authorization server redirects back to
redirect_uriwith a short-lived authorization code. - The client (server-side) exchanges the code for tokens by posting to the token endpoint — this call includes the
client_secret, which never leaves the server. - The authorization server returns an
access_token, optionally arefresh_token, and (if OIDC) anid_token.
PKCE (Proof Key for Code Exchange) was originally designed for mobile apps that cannot keep a client secret, but RFC 9700 now mandates it for all public clients (SPAs, mobile). The client generates a random code_verifier, hashes it to produce a code_challenge, and sends the challenge in step 1. In step 4, it sends the plain verifier, and the authorization server checks it. This prevents an attacker who intercepts the code from being able to exchange it.
state parameter on the callback. It is a CSRF token — without checking it, an attacker can perform a CSRF login attack and link their account to the victim's session.
2. Client Credentials Grant
Used for machine-to-machine (M2M) communication — a microservice calling another microservice with no human user involved. The client authenticates directly with its own credentials; there is no browser redirect and no resource owner consent.
The response is an access token scoped to what the service is allowed to do. This is the grant type you will configure in Spring Security when your microservice needs to call an upstream API.
3. Refresh Token Grant
Access tokens are intentionally short-lived (typically 5–15 minutes). When an access token expires, the client can use a refresh token — which was issued alongside the access token and has a longer lifetime — to silently obtain a new access token without bothering the user.
4. Implicit Grant (Deprecated)
The implicit grant returned an access token directly from the authorization endpoint — no code exchange, no client secret. It was designed for browser SPAs before PKCE existed but has fundamental security flaws (tokens visible in the URL fragment, no sender binding). Do not use it in new applications. Replace it with Authorization Code + PKCE.
OpenID Connect (OIDC) — Adding Identity
OAuth 2.0 tells a resource server what the client is allowed to do. It does not tell your application who the user is. OpenID Connect is a thin identity layer built on top of OAuth 2.0 that adds exactly that.
When a client requests the openid scope, the authorization server includes an ID Token in the token response alongside the access token. An ID Token is a signed JWT that contains:
iss— the issuer URI (authorization server).sub— the subject identifier (the user's unique ID at the issuer).aud— the intended audience (your client ID).expandiat— expiry and issued-at timestamps.nonce— a value you sent in the authorization request, preventing replay attacks.- Standard profile claims:
name,email,picture,locale, etc. (gated on scopes likeprofile,email).
The client must validate the ID Token before trusting any claim: verify the signature against the issuer's JWKS endpoint, confirm iss, aud, exp, and nonce. Spring Security's OAuth2 Login does all of this automatically.
Scopes and the UserInfo Endpoint
OAuth2 scopes define what an access token is permitted to do. OIDC defines standard scopes:
openid— required to trigger OIDC; returns the ID Token.profile— name, family_name, given_name, picture, locale.email— email and email_verified.addressandphone— postal address, phone number.offline_access— requests a refresh token.
Additional claims not present in the ID Token can be fetched from the UserInfo endpoint — a protected REST endpoint on the authorization server that accepts the access token and returns the user's attributes. Spring Security calls this automatically when you configure OAuth2 Login.
The Discovery Document
Any OIDC-compliant authorization server publishes a discovery document at /.well-known/openid-configuration. It lists every endpoint URL, supported scopes, signing algorithms, and JWKS URI. Spring Security reads this automatically when you set spring.security.oauth2.resourceserver.jwt.issuer-uri — you do not need to configure endpoints manually.
OAuth2 vs Your Custom JWT Setup
The JWTs you generated in lessons 3–5 are proprietary tokens — your application is both the issuer and the validator. That works well for simple systems. OAuth2/OIDC is appropriate when:
- You want users to log in with a third-party identity provider (Google, GitHub, corporate IdP).
- You operate multiple services and want a single authorization server to issue tokens all services trust.
- You need delegated API access — allowing a third-party app to call your API on behalf of a user.
- Compliance requires standards-based identity (FIDO2, enterprise SSO, audit trails).
Summary
OAuth 2.0 defines four roles (resource owner, client, authorization server, resource server) and multiple grant types for each scenario: Authorization Code + PKCE for user-facing apps, Client Credentials for machine-to-machine calls, and Refresh Token for silent renewal. OpenID Connect layers identity on top by adding the ID Token — a signed JWT carrying the user's identity claims. In the next lesson you will configure your Spring Boot application as an OAuth2 Resource Server that validates JWTs issued by an external authorization server.