The authorization code flow, hop by hop

Spring Security · lesson 23 of 31 · 4 min read

Follow a browser through redirect, code and token exchange, and see what PKCE actually protects.

Open this lesson in the learning hub

Key points

  • Hitting a protected page redirects the browser to the provider with response_type=code and a random state.
  • The password is typed at the provider, never at your app. That is the entire reason the redirect exists.
  • The provider redirects back to /login/oauth2/code/{registrationId} with a short-lived, single-use code.
  • Your server then swaps that code for tokens over the back channel, so no token ever appears in the URL bar.
  • PKCE sends a hash up front and the original secret at exchange time, which makes a stolen code useless on its own.
  • state is the CSRF defence for the redirect itself: a callback carrying the wrong state is dropped.

Example

# 1. GET /oauth2/authorization/google   -> 302 to the provider (+ state, + PKCE challenge)
# 2. provider sends the browser back to /login/oauth2/code/google?code=...&state=...
# 3. your server posts the code + verifier to the token endpoint, back channel only
spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: set-from-an-environment-variable
            client-secret: set-from-an-environment-variable
            scope: openid, profile, email
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
        provider:
          google:
            issuer-uri: https://accounts.google.com

# in the chain: http.oauth2Login(Customizer.withDefaults());

The browser carries a code, never a token, and PKCE makes a stolen code worthless.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Spring Security course, and every lesson in it is listed on the Spring Security contents page.