liveBook · Manning

API key

As explained in Spring in Action, Sixth Edition

An access token is a credential that authorizes a client to access protected resources on behalf of a user or other resource owner.

For these protected API calls, the credential is an OAuth 2 access token. Think of it as a ticket: the API checks whether the client may perform an action without asking for the user’s password on every request. An authorization server issues the token with the user’s permission; the client sends it when calling the API. section 8.1

In the authorization code flow:

  • The client redirects the user to the authorization server for login and consent. section 8.4
  • The authorization server returns an authorization code, which the client exchanges for an access token. section 8.4
  • The client sends the token as an Authorization: Bearer header on API requests. section 8.2
{
  "access_token":"eyJraWQ...",
  "refresh_token":"HOzHA5s...",
  "scope":"deleteIngredients writeIngredients",
  "token_type":"Bearer",
  "expires_in":"299"
}

The token response includes an access_token, its Bearer token type, granted scopes, and an expiry time. It also includes a refresh_token for requesting another access token later. section 8.2

The resource server checks the token before allowing protected requests. In the ingredient API, POST requires the writeIngredients scope and DELETE requires deleteIngredients. Spring Security matches those scopes through SCOPE_-prefixed authorities, inspects JWT claims, and verifies the token’s signature using the authorization server’s public key. A token is therefore more than a string to attach: it must be valid and grant the requested action. section 8.3

@Bean
@RequestScope
public IngredientService ingredientService(
              OAuth2AuthorizedClientService clientService) {
  Authentication authentication = 
          SecurityContextHolder.getContext().getAuthentication();
  
  String accessToken = null;
  
  if (authentication.getClass()
            .isAssignableFrom(OAuth2AuthenticationToken.class)) {
    OAuth2AuthenticationToken oauthToken = 
            (OAuth2AuthenticationToken) authentication;
    String clientRegistrationId = 
            oauthToken.getAuthorizedClientRegistrationId();
    if (clientRegistrationId.equals("taco-admin-client")) {
      OAuth2AuthorizedClient client = 
          clientService.loadAuthorizedClient(
              clientRegistrationId, oauthToken.getName());
      accessToken = client.getAccessToken().getTokenValue();
    }
  }
  return new RestIngredientService(accessToken);
}

This request-scoped service loads the authenticated client’s access token and passes its value to the REST service that makes API calls. section 8.4

Adding an ingredient

A client can POST a JSON ingredient with Authorization: Bearer $token. Without a suitable token, the protected write request cannot pass the resource server’s check. When the access token expires, the client can use its refresh token to request a new one rather than ask the user to change a password. section 8.3 section 8.2

How Spring in Action, Sixth Edition covers it

How deep it goes
Works through token issuance, bearer requests, scope checks, JWT verification, and refresh; does not develop every OAuth 2 grant type.
Examples
Uses ingredient-API POST and DELETE requests, a token response, curl bearer requests, and a Spring REST client.
What it assumes
Assumes a Spring Boot REST application and builds the separate authorization server and client configuration from that starting point.
What you can do after
Apply it via Spring Security to obtain an access token, forward it with API requests, and enforce scoped access.
How it connects
Connects OAuth 2 authorization code flow, authorization servers, resource servers, bearer authentication, JWTs, scopes, and refresh tokens.

Also explained in

Compare how 13 books explain API key →

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.