What is an OAuth2AuthorizedClient in Spring Security, and how does oauth2Client() differ from oauth2Login()?
answer
- AuthorizedClient = registration + principal + access token (+ refresh)
- oauth2Login = identity; oauth2Client = calling APIs
- code grant filters: RedirectFilter + AuthorizationCodeGrantFilter
- stored by Service (app-wide) or Repository (per-request)
- getAccessToken().getTokenValue() -> Bearer header
basics
~20 sAn OAuth2AuthorizedClient holds the access token (and optional refresh token) your app got to call another API on a user's behalf. oauth2Client() lets your app CALL other APIs; oauth2Login() logs the USER into your app.
solid answer
~40 sOAuth2AuthorizedClient represents a successful authorization: it bundles the ClientRegistration (which provider), the principal name, the OAuth2AccessToken, and optionally an OAuth2RefreshToken. It is the object you use to attach a bearer token when calling a downstream/third-party API. `oauth2Client()` in the HttpSecurity DSL enables the OAuth2 Client feature — the filters that obtain and store these tokens so your application can act as a client of another OAuth2/OIDC provider. That is different from `oauth2Login()`, which uses OAuth2/OIDC purely to authenticate the end user into YOUR app and establish their Authentication. You can enable both: log the user in with oauth2Login and also hold authorized clients for calling APIs. Authorized clients are stored via OAuth2AuthorizedClientService/Repository and retrieved by registration id.
code
java · 18 lines@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain chain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(a -> a.anyRequest().authenticated())
// Log the USER in via OIDC ...
.oauth2Login(Customizer.withDefaults())
// ... and ALSO enable acting as an OAuth2 client to call APIs.
.oauth2Client(Customizer.withDefaults());
return http.build();
}
}
// registrationId + principalName identify a stored OAuth2AuthorizedClient
// client.getAccessToken().getTokenValue() -> the bearer token you send downstreamgo deeper
Know the object holds an access token and that oauth2Client is about calling APIs, not logging users in.
Should name the two filters, the Service vs Repository stores, and that registrations come from properties.
Explain that oauth2Login builds on the client feature and how the authorized client feeds downstream API calls (WebClient/RestClient).
Discuss token storage strategy (JDBC vs in-memory), principal keying for M2M, and multi-tenant registration repositories.
## The core object An **`OAuth2AuthorizedClient`** is Spring Security's record that 'client X has been authorized to act for principal P'. It contains four things: - **`ClientRegistration`** — the provider config (client-id, secret, token endpoint, scopes, grant type). Identified by a **`registrationId`** (e.g. `github`, `my-api`). - **`principalName`** — whose authorization this is (a username, or the client-id itself for machine-to-machine). - **`OAuth2AccessToken`** — the bearer token you send to the resource server, plus its scopes and expiry. - **`OAuth2RefreshToken`** — optional; used to get a fresh access token without re-prompting. You use it like: `authorizedClient.getAccessToken().getTokenValue()` → put that in an `Authorization: Bearer …` header when calling a downstream API. ## Two very different features Spring Security has two OAuth2 client-side features that beginners conflate: 1. **`oauth2Login()`** — the app is a **Relying Party for authentication**. The user signs in through Google/GitHub; Spring creates an `Authentication` (an `OAuth2AuthenticationToken` / `OidcUser`) and the user is logged into your app. The point is *identity*. 2. **`oauth2Client()`** — the app is an **OAuth2 client that calls protected resources**. The point is *access* — obtaining and storing access tokens so your code can call other APIs. `oauth2Login()` actually builds on the client feature, but you can enable `oauth2Client()` alone if you only need to call APIs and authenticate users some other way (form login, JWT, etc.). `oauth2Client()` in the DSL registers two filters for the authorization_code flow: **`OAuth2AuthorizationRequestRedirectFilter`** (kicks off the redirect to the provider) and **`OAuth2AuthorizationCodeGrantFilter`** (handles the callback, exchanges the code for a token, and stores the resulting `OAuth2AuthorizedClient`). ## Where authorized clients live - **`OAuth2AuthorizedClientService`** — application-wide store (in-memory `InMemoryOAuth2AuthorizedClientService` by default, or `JdbcOAuth2AuthorizedClientService`). Keyed by (registrationId, principalName). Good for background/shared access. - **`OAuth2AuthorizedClientRepository`** — request-scoped view (works with `HttpServletRequest`); the default `AuthenticatedPrincipalOAuth2AuthorizedClientRepository` delegates to the service for authenticated users and to the HTTP session for anonymous ones. ## Configuration Registrations come from `spring.security.oauth2.client.registration.*` and `….provider.*` properties, materialized as a `ClientRegistrationRepository` bean. ## When to use Use `oauth2Client()` whenever your service must call a third-party or internal API that is protected by OAuth2 — regardless of how your own users authenticate.
- Can you use oauth2Client() without oauth2Login()?Yes. You can authenticate users with form login or a JWT resource-server config and still enable oauth2Client() purely to obtain access tokens for calling downstream APIs. oauth2Login is not a prerequisite.
- What identifies a ClientRegistration?Its registrationId — the key under spring.security.oauth2.client.registration.<id>. You reference that same id in @RegisteredOAuth2AuthorizedClient("<id>") and when loading from the service.
saying these in an interview costs you the question
- Saying oauth2Client() logs the user in (that's oauth2Login()).
- Claiming the AuthorizedClient stores the user's password.
- Confusing it with oauth2ResourceServer() or Spring Authorization Server.