liveBook · Manning

Authorization code flow

As explained in Spring in Action, Sixth Edition

An OAuth2 flow in which a client exchanges a short-lived authorization code for an access token after the resource owner grants consent.

The authorization code flow lets an application call a protected API on a user’s behalf without asking the application to handle the user’s password. The client sends the user’s browser to an authorization server for login and consent. After the user agrees, the authorization server redirects the browser back with an authorization code. The client exchanges that code for an access token, then sends the token when calling the API. section 8.1 section 8.4

Picture an ingredient-management application. Its client needs permission to write and delete ingredients through a REST API. Three applications have distinct jobs: the client requests permission and calls the API; the authorization server authenticates the user and issues tokens; the API accepts the token for protected requests. The client’s registered scopes specify the permissions it requests. section 8.2 section 8.4

To make that round trip work:

  • Register the client with the authorization server using its client ID, secret, authorization-code grant type, redirect URI, requested scopes, and a requirement for user consent. section 8.2
  • Configure the client with matching credentials and redirect URI, the requested scopes, and the authorization server’s provider details. Enable OAuth 2 login so an unauthenticated user is sent through authorization. section 8.4
  • After consent, exchange the returned code at the token endpoint. Use the resulting bearer access token in requests to the protected API. section 8.2 section 8.4
@Bean
public RegisteredClientRepository registeredClientRepository(
        PasswordEncoder passwordEncoder) {
  RegisteredClient registeredClient = 
    RegisteredClient.withId(UUID.randomUUID().toString())
      .clientId("taco-admin-client")
      .clientSecret(passwordEncoder.encode("secret"))
      .clientAuthenticationMethod(
              ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
      .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
      .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
      .redirectUri(
          "http://127.0.0.1:9090/login/oauth2/code/taco-admin-client")
      .scope("writeIngredients")
      .scope("deleteIngredients")
      .scope(OidcScopes.OPENID)
      .clientSettings(
          clientSettings -> clientSettings.requireUserConsent(true))
      .build();
  return new InMemoryRegisteredClientRepository(registeredClient);
}

The server-side registration enables AUTHORIZATION_CODE, sets the redirect URI and scopes, and requires consent; these choices define what this client may request. section 8.2

spring:
  security:
    oauth2:
      client:
        registration:
          taco-admin-client:
            provider: tacocloud
            client-id: taco-admin-client
            client-secret: secret
            authorization-grant-type: authorization_code
            redirect-uri: 
                 "http://127.0.0.1:9090/login/oauth2/code/{registrationId}"
            scope: writeIngredients,deleteIngredients,openid

The client-side YAML selects authorization_code and supplies the credentials, scopes, and callback URI that must line up with its server-side registration. section 8.4

Exchange the code, then call the API

A token request posts grant_type=authorization_code, the redirect URI, and the returned code to /oauth2/token while authenticating the client. The response includes a bearer access token and, in this example, a refresh token. The client can put the access token in an Authorization: Bearer header when adding an ingredient. Access tokens can expire or be revoked; the user’s password need not change when that happens. section 8.2 section 8.1

For a Spring Boot client, spring-boot-starter-oauth2-client and an OAuth 2-enabled SecurityFilterChain handle the login integration. An authorized-client service can retrieve the user’s access token, and a RestTemplate interceptor can attach it to API requests. The authorization code is thus an intermediate step, not the credential sent to the ingredient API. section 8.4

How Spring in Action, Sixth Edition covers it

How deep it goes
Works through consent, redirects, code exchange, server and client configuration, and bearer requests; does not detail OAuth 2 specification internals.
Examples
Uses an ingredient-management client, registered-client and YAML configurations, a curl token exchange, and an authenticated ingredient request.
What it assumes
Assumes a Spring Boot REST application and introduces OAuth 2 roles before configuring separate authorization-server and client applications.
What you can do after
Apply it via Spring Authorization Server and Spring Security OAuth 2 client support to obtain tokens and call a protected API.
How it connects
Connects OAuth 2 consent, authorization servers, resource servers, scopes, bearer tokens, refresh tokens, and Spring Security OAuth 2 clients.

Also explained in

Compare how 8 books explain authorization code flow →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Spring in Action, Sixth Edition. The section links point to the parts of the book it draws on.