OpenID Connect and ID Tokens

What OIDC Adds

OpenID Connect adds three things on top of OAuth2:

  • The openid scope: asking for it turns an OAuth2 flow into an OIDC login.
  • The ID token: a signed JWT that tells the client who logged in.
  • Standard endpoints: /.well-known/openid-configuration (discovery), /userinfo, and the JWKS endpoint with the public signing keys.

Inside an ID Token

{
  "iss": "https://accounts.google.com",
  "aud": "1234567890-abc123.apps.googleusercontent.com",
  "sub": "110248495921238986420",
  "email": "[email protected]",
  "email_verified": true,
  "name": "Asha Verma",
  "picture": "https://lh3.googleusercontent.com/a/ACg8ocK...",
  "nonce": "n-0S6_WzA2Mj",
  "iat": 1772359200,
  "exp": 1772362800
}
ClaimMeaningClient must check
issWho issued the tokenEquals the expected issuer
audWhich client it is forContains your client_id
subStable, unique user id at that providerUse this (not email) as the external id
exp / iatExpiry / issued-at (seconds since epoch)Not expired
nonceValue the client sent in the requestEquals the nonce you stored (stops replay)
email_verifiedProvider confirmed the emailBe true before linking to an existing account

Note: Use sub + iss as the user's identity key. Emails can change and, at some providers, can be unverified — linking accounts on an unverified email is a classic account-takeover bug.

Discovery Document

OIDC discovery

Spring Security only needs the issuer URI; it reads everything else from the discovery document:

curl -s https://accounts.google.com/.well-known/openid-configuration

Example output

{
  "issuer": "https://accounts.google.com",
  "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
  "token_endpoint": "https://oauth2.googleapis.com/token",
  "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
  "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
  "response_types_supported": ["code", "token", "id_token", "code token", "code id_token", "none"],
  "scopes_supported": ["openid", "email", "profile"],
  "id_token_signing_alg_values_supported": ["RS256"],
  "code_challenge_methods_supported": ["plain", "S256"]
}