An OAuth2 authorized client pairs a client registration with an access token obtained for a grant. For a machine-to-machine call, the client-credentials grant represents the calling service, not an end user.
Spring OAuth2 client credentials: acquire and reuse a service token
Authorize at the outbound boundary
Inject an OAuth2AuthorizedClientManager configured for the grant your service uses. Ask it to authorize before sending the request so token acquisition and renewal follow one policy. Reusing a single service principal key lets the authorized-client store find that service registration again; it must never be used to impersonate a browser user.
package in.aitrove.receipts;
import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
class StockServiceToken {
private final OAuth2AuthorizedClientManager authorizedClients;
StockServiceToken(OAuth2AuthorizedClientManager authorizedClients) {
this.authorizedClients = authorizedClients;
}
String accessToken() {
OAuth2AuthorizeRequest request = OAuth2AuthorizeRequest
.withClientRegistrationId("stock-service")
.principal("receipt-relay")
.build();
OAuth2AuthorizedClient client = authorizedClients.authorize(request);
if (client == null) {
throw new IllegalStateException("Stock service authorization failed");
}
return client.getAccessToken().getTokenValue();
}
}The returned token is a secret. Pass it as a bearer header to the intended resource server, but do not place it in logs, URL parameters or metrics labels. The server must validate issuer, audience and scopes according to its own trust policy. A token request can fail before the stock API is called; an API 503 can fail after the token was acquired. They deserve different retry decisions.
Budget for expiry and concurrency
Token expiry may trigger an extra network call at the worst point in a request. Bound acquisition time inside the overall request deadline. When many workers need a token simultaneously, test whether the authorized-client store and manager avoid duplicate token requests under your deployment pattern; do not assume an in-memory cache is shared across replicas.
Common Mistakes
- Using a browser authorization-code client for an unattended relay.
- Treating a null authorize result as a usable empty token.
- Retrying a downstream POST merely because the token was refreshed.
- Sharing one client secret across environments without an explicit rotation plan.
Read next
Resource-server validation, outbound timeout budgets, and uncertain POST commits.
