# Authorized Client Features ## Resolving an Authorized Client The `@RegisteredOAuth2AuthorizedClient` annotation provides the capability of resolving a method parameter to an argument value of type `OAuth2AuthorizedClient`. This is a convenient alternative compared to accessing the `OAuth2AuthorizedClient` using the `OAuth2AuthorizedClientManager` or `OAuth2AuthorizedClientService`. Java ``` @Controller public class OAuth2ClientController { @GetMapping("/") public String index(@RegisteredOAuth2AuthorizedClient("okta") OAuth2AuthorizedClient authorizedClient) { OAuth2AccessToken accessToken = authorizedClient.getAccessToken(); ... return "index"; } } ``` Kotlin ``` @Controller class OAuth2ClientController { @GetMapping("/") fun index(@RegisteredOAuth2AuthorizedClient("okta") authorizedClient: OAuth2AuthorizedClient): String { val accessToken = authorizedClient.accessToken ... return "index" } } ``` The `@RegisteredOAuth2AuthorizedClient` annotation is handled by `OAuth2AuthorizedClientArgumentResolver`, which directly uses an [`OAuth2AuthorizedClientManager`](core.html#oauth2Client-authorized-manager-provider) and therefore inherits it’s capabilities. ## WebClient integration for Servlet Environments The OAuth 2.0 Client support integrates with `WebClient` using an `ExchangeFilterFunction`. The `ServletOAuth2AuthorizedClientExchangeFilterFunction` provides a simple mechanism for requesting protected resources by using an `OAuth2AuthorizedClient` and including the associated `OAuth2AccessToken` as a Bearer Token. It directly uses an [`OAuth2AuthorizedClientManager`](core.html#oauth2Client-authorized-manager-provider) and therefore inherits the following capabilities: * An `OAuth2AccessToken` will be requested if the client has not yet been authorized. * `authorization_code` - triggers the Authorization Request redirect to initiate the flow * `client_credentials` - the access token is obtained directly from the Token Endpoint * `password` - the access token is obtained directly from the Token Endpoint * If the `OAuth2AccessToken` is expired, it will be refreshed (or renewed) if an `OAuth2AuthorizedClientProvider` is available to perform the authorization The following code shows an example of how to configure `WebClient` with OAuth 2.0 Client support: Java ``` @Bean WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) { ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client = new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); return WebClient.builder() .apply(oauth2Client.oauth2Configuration()) .build(); } ``` Kotlin ``` @Bean fun webClient(authorizedClientManager: OAuth2AuthorizedClientManager?): WebClient { val oauth2Client = ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager) return WebClient.builder() .apply(oauth2Client.oauth2Configuration()) .build() } ``` ### Providing the Authorized Client The `ServletOAuth2AuthorizedClientExchangeFilterFunction` determines the client to use (for a request) by resolving the `OAuth2AuthorizedClient` from the `ClientRequest.attributes()` (request attributes). The following code shows how to set an `OAuth2AuthorizedClient` as a request attribute: Java ``` @GetMapping("/") public String index(@RegisteredOAuth2AuthorizedClient("okta") OAuth2AuthorizedClient authorizedClient) { String resourceUri = ... String body = webClient .get() .uri(resourceUri) .attributes(oauth2AuthorizedClient(authorizedClient)) (1) .retrieve() .bodyToMono(String.class) .block(); ... return "index"; } ``` Kotlin ``` @GetMapping("/") fun index(@RegisteredOAuth2AuthorizedClient("okta") authorizedClient: OAuth2AuthorizedClient): String { val resourceUri: String = ... val body: String = webClient .get() .uri(resourceUri) .attributes(oauth2AuthorizedClient(authorizedClient)) (1) .retrieve() .bodyToMono() .block() ... return "index" } ``` |**1**|`oauth2AuthorizedClient()` is a `static` method in `ServletOAuth2AuthorizedClientExchangeFilterFunction`.| |-----|---------------------------------------------------------------------------------------------------------| The following code shows how to set the `ClientRegistration.getRegistrationId()` as a request attribute: Java ``` @GetMapping("/") public String index() { String resourceUri = ... String body = webClient .get() .uri(resourceUri) .attributes(clientRegistrationId("okta")) (1) .retrieve() .bodyToMono(String.class) .block(); ... return "index"; } ``` Kotlin ``` @GetMapping("/") fun index(): String { val resourceUri: String = ... val body: String = webClient .get() .uri(resourceUri) .attributes(clientRegistrationId("okta")) (1) .retrieve() .bodyToMono() .block() ... return "index" } ``` |**1**|`clientRegistrationId()` is a `static` method in `ServletOAuth2AuthorizedClientExchangeFilterFunction`.| |-----|-------------------------------------------------------------------------------------------------------| ### Defaulting the Authorized Client If neither `OAuth2AuthorizedClient` or `ClientRegistration.getRegistrationId()` is provided as a request attribute, the `ServletOAuth2AuthorizedClientExchangeFilterFunction` can determine the *default* client to use depending on it’s configuration. If `setDefaultOAuth2AuthorizedClient(true)` is configured and the user has authenticated using `HttpSecurity.oauth2Login()`, the `OAuth2AccessToken` associated with the current `OAuth2AuthenticationToken` is used. The following code shows the specific configuration: Java ``` @Bean WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) { ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client = new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); oauth2Client.setDefaultOAuth2AuthorizedClient(true); return WebClient.builder() .apply(oauth2Client.oauth2Configuration()) .build(); } ``` Kotlin ``` @Bean fun webClient(authorizedClientManager: OAuth2AuthorizedClientManager?): WebClient { val oauth2Client = ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager) oauth2Client.setDefaultOAuth2AuthorizedClient(true) return WebClient.builder() .apply(oauth2Client.oauth2Configuration()) .build() } ``` | |It is recommended to be cautious with this feature since all HTTP requests will receive the access token.| |---|---------------------------------------------------------------------------------------------------------| Alternatively, if `setDefaultClientRegistrationId("okta")` is configured with a valid `ClientRegistration`, the `OAuth2AccessToken` associated with the `OAuth2AuthorizedClient` is used. The following code shows the specific configuration: Java ``` @Bean WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) { ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client = new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); oauth2Client.setDefaultClientRegistrationId("okta"); return WebClient.builder() .apply(oauth2Client.oauth2Configuration()) .build(); } ``` Kotlin ``` @Bean fun webClient(authorizedClientManager: OAuth2AuthorizedClientManager?): WebClient { val oauth2Client = ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager) oauth2Client.setDefaultClientRegistrationId("okta") return WebClient.builder() .apply(oauth2Client.oauth2Configuration()) .build() } ``` | |It is recommended to be cautious with this feature since all HTTP requests will receive the access token.| |---|---------------------------------------------------------------------------------------------------------| [OAuth2 Client Authentication](client-authentication.html)[OAuth2 Resource Server](../resource-server/index.html)