| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 | To opt-in to using `{class-name}`, simply provide a bean as in the following example and it will be picked up by the default `OAuth2AuthorizedClientManager` automatically:[#oauth2-client-{section-id}-access-token-response-client-bean].Access Token Response Configuration[tabs]======Java::+[source,java,role="primary",subs="+attributes"]----@Beanpublic OAuth2AccessTokenResponseClient<{grant-request}> accessTokenResponseClient() {	return new {class-name}();}----Kotlin::+[source,kotlin,role="secondary",subs="+attributes"]----@Beanfun accessTokenResponseClient(): OAuth2AccessTokenResponseClient<{grant-type}> {	return {class-name}()}----======[NOTE]====The new implementation will be the default in Spring Security 7.====`{class-name}` is very flexible and provides several options for customizing the OAuth 2.0 Access Token request and response for the {grant-type} grant.Choose from the following use cases to learn more:* I want to <<oauth2-client-{section-id}-access-token-request-headers,customize headers of the Access Token request>>* I want to <<oauth2-client-{section-id}-access-token-request-parameters,customize parameters of the Access Token request>>* I want to <<oauth2-client-{section-id}-access-token-response-rest-client,customize the instance of `RestClient` that is used>>* I want to <<oauth2-client-{section-id}-access-token-response-parameters,customize parameters of the Access Token response>>* I want to <<oauth2-client-{section-id}-access-token-response-errors,customize error handling of the Access Token response>>[#oauth2-client-{section-id}-access-token-request]== Customizing the Access Token Request`{class-name}` provides hooks for customizing HTTP headers and request parameters of the OAuth 2.0 Access Token Request.[#oauth2-client-{section-id}-access-token-request-headers]=== Customizing Request HeadersThere are two options for customizing HTTP headers:* Add additional headers by calling `addHeadersConverter()`* Fully customize headers by calling `setHeadersConverter()`You can include additional headers without affecting the default headers added to every request using `addHeadersConverter()`.The following example adds a `User-Agent` header to the request when the `registrationId` is `spring`:.Include Additional HTTP Headers[tabs]======Java::+[source,java,role="primary",subs="+attributes"]----{class-name} accessTokenResponseClient =	new {class-name}();accessTokenResponseClient.addHeadersConverter(grantRequest -> {	ClientRegistration clientRegistration = grantRequest.getClientRegistration();	HttpHeaders headers = new HttpHeaders();	if (clientRegistration.getRegistrationId().equals("spring")) {		headers.set(HttpHeaders.USER_AGENT, "my-user-agent");	}	return headers;});----Kotlin::+[source,kotlin,role="secondary",subs="+attributes"]----val accessTokenResponseClient = {class-name}()accessTokenResponseClient.addHeadersConverter { grantRequest ->	val clientRegistration = grantRequest.getClientRegistration()	val headers = HttpHeaders()	if (clientRegistration.getRegistrationId() == "spring") {        headers[HttpHeaders.USER_AGENT] = "my-user-agent"	}	headers}----======You can fully customize headers by re-using `DefaultOAuth2TokenRequestHeadersConverter` or providing a custom implementation using `setHeadersConverter()`.The following example re-uses `DefaultOAuth2TokenRequestHeadersConverter` and disables `encodeClientCredentials` so that HTTP Basic credentials are no longer encoded with `application/x-www-form-urlencoded`:.Customize HTTP Headers[tabs]======Java::+[source,java,role="primary",subs="+attributes"]----DefaultOAuth2TokenRequestHeadersConverter headersConverter =	new DefaultOAuth2TokenRequestHeadersConverter();headersConverter.setEncodeClientCredentials(false);{class-name} accessTokenResponseClient =	new {class-name}();accessTokenResponseClient.setHeadersConverter(headersConverter);----Kotlin::+[source,kotlin,role="secondary",subs="+attributes"]----val headersConverter = DefaultOAuth2TokenRequestHeadersConverter()headersConverter.setEncodeClientCredentials(false)val accessTokenResponseClient = {class-name}()accessTokenResponseClient.setHeadersConverter(headersConverter)----======[#oauth2-client-{section-id}-access-token-request-parameters]=== Customizing Request ParametersThere are three options for customizing request parameters:* Add additional parameters by calling `addParametersConverter()`* Override parameters by calling `setParametersConverter()`* Fully customize parameters by calling `setParametersCustomizer()`[NOTE]====Using `setParametersConverter()` does not fully customize parameters because it would require the user to provide all default parameters themselves.Default parameters are always provided, but can be fully customized or omitted by calling `setParametersCustomizer()`.====You can include additional parameters without affecting the default parameters added to every request using `addParametersConverter()`.The following example adds an `audience` parameter to the request when the `registrationId` is `keycloak`:.Include Additional Request Parameters[tabs]======Java::+[source,java,role="primary",subs="+attributes"]----{class-name} accessTokenResponseClient =	new {class-name}();accessTokenResponseClient.addParametersConverter(grantRequest -> {	ClientRegistration clientRegistration = grantRequest.getClientRegistration();	MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>();	if (clientRegistration.getRegistrationId().equals("keycloak")) {		parameters.set(OAuth2ParameterNames.AUDIENCE, "my-audience");	}	return parameters;});----Kotlin::+[source,kotlin,role="secondary",subs="+attributes"]----val accessTokenResponseClient = {class-name}()accessTokenResponseClient.addParametersConverter { grantRequest ->	val clientRegistration = grantRequest.getClientRegistration()	val parameters = LinkedMultiValueMap<String, String>()	if (clientRegistration.getRegistrationId() == "keycloak") {        parameters[OAuth2ParameterNames.AUDIENCE] = "my-audience"	}	parameters}----======You can override default parameters using `setParametersConverter()`.The following example overrides the `client_id` parameter when the `registrationId` is `okta`:.Override Request Parameters[tabs]======Java::+[source,java,role="primary",subs="+attributes"]----{class-name} accessTokenResponseClient =	new {class-name}();accessTokenResponseClient.setParametersConverter(grantRequest -> {	ClientRegistration clientRegistration = grantRequest.getClientRegistration();	LinkedMultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();	if (clientRegistration.getRegistrationId().equals("okta")) {		parameters.set(OAuth2ParameterNames.CLIENT_ID, "my-client");	}	return parameters;});----Kotlin::+[source,kotlin,role="secondary",subs="+attributes"]----val parametersConverter = DefaultOAuth2TokenRequestParametersConverter<{grant-request}>()parametersConverter.setParametersCustomizer { parameters ->	if (parameters.containsKey(OAuth2ParameterNames.CLIENT_ASSERTION)) {		parameters.remove(OAuth2ParameterNames.CLIENT_ID)	}}val accessTokenResponseClient = {class-name}()accessTokenResponseClient.setParametersConverter { grantRequest ->    val clientRegistration = grantRequest.getClientRegistration()	val parameters = LinkedMultiValueMap<String, String>()	if (clientRegistration.getRegistrationId() == "okta") {        parameters[OAuth2ParameterNames.CLIENT_ID] = "my-client"	}	parameters}----======You can fully customize parameters (including omitting default parameters) using `setParametersCustomizer()`.The following example omits the `client_id` parameter when the `client_assertion` parameter is present in the request:.Omit Request Parameters[tabs]======Java::+[source,java,role="primary",subs="+attributes"]----{class-name} accessTokenResponseClient =	new {class-name}();accessTokenResponseClient.setParametersCustomizer(parameters -> {	if (parameters.containsKey(OAuth2ParameterNames.CLIENT_ASSERTION)) {		parameters.remove(OAuth2ParameterNames.CLIENT_ID);	}});----Kotlin::+[source,kotlin,role="secondary",subs="+attributes"]----val accessTokenResponseClient = {class-name}()accessTokenResponseClient.setParametersCustomizer { parameters ->	if (parameters.containsKey(OAuth2ParameterNames.CLIENT_ASSERTION)) {		parameters.remove(OAuth2ParameterNames.CLIENT_ID)	}}----======[#oauth2-client-{section-id}-access-token-response]== Customizing the Access Token Response`{class-name}` provides hooks for customizing response parameters and error handling of the OAuth 2.0 Access Token Response.[#oauth2-client-{section-id}-access-token-response-rest-client]=== Customizing the `RestClient`You can customize the Token Response by providing a pre-configured `RestClient` to `setRestClient()`.The default `RestClient` is configured as follows:.Default `RestClient` Configuration[tabs]======Java::+[source,java,role="primary",subs="+attributes"]----RestClient restClient = RestClient.builder()	.messageConverters(messageConverters -> {		messageConverters.clear();		messageConverters.add(new FormHttpMessageConverter());		messageConverters.add(new OAuth2AccessTokenResponseHttpMessageConverter());	})	.defaultStatusHandler(new OAuth2ErrorResponseErrorHandler())	.build();{class-name} accessTokenResponseClient =	new {class-name}();accessTokenResponseClient.setRestClient(restClient);----Kotlin::+[source,kotlin,role="secondary",subs="+attributes"]----val restClient = RestClient.builder()	.messageConverters { messageConverters ->		messageConverters.clear()		messageConverters.add(FormHttpMessageConverter())		messageConverters.add(OAuth2AccessTokenResponseHttpMessageConverter())	}	.defaultStatusHandler(OAuth2ErrorResponseErrorHandler())	.build()val accessTokenResponseClient = {class-name}()accessTokenResponseClient.setRestClient(restClient)----======`OAuth2AccessTokenResponseHttpMessageConverter` is an `HttpMessageConverter` for an OAuth 2.0 Access Token Response.You can customize the conversion of Token Response parameters to an `OAuth2AccessTokenResponse` by calling `setAccessTokenResponseConverter()`.The default implementation is `DefaultMapOAuth2AccessTokenResponseConverter`.`OAuth2ErrorResponseErrorHandler` is a `ResponseErrorHandler` that can handle an OAuth 2.0 Error, such as `400 Bad Request`.It uses an `OAuth2ErrorHttpMessageConverter` for converting the OAuth 2.0 Error parameters to an `OAuth2Error`.You can customize the conversion of Token Response parameters to an `OAuth2Error` by calling `setErrorConverter()`.[TIP]====Spring MVC `FormHttpMessageConverter` is required, as it is used when sending the OAuth 2.0 Access Token Request.====[#oauth2-client-{section-id}-access-token-response-parameters]=== Customizing Response ParametersThe following example provides a starting point for customizing the conversion of Token Response parameters to an `OAuth2AccessTokenResponse`:.Customize Access Token Response Converter[tabs]======Java::+[source,java,role="primary"]----OAuth2AccessTokenResponseHttpMessageConverter accessTokenResponseMessageConverter =	new OAuth2AccessTokenResponseHttpMessageConverter();accessTokenResponseMessageConverter.setAccessTokenResponseConverter(parameters -> {	// ...	return OAuth2AccessTokenResponse.withToken("custom-token")		// ...		.build();});----Kotlin::+[source,kotlin,role="secondary"]----val accessTokenResponseMessageConverter = OAuth2AccessTokenResponseHttpMessageConverter()accessTokenResponseMessageConverter.setAccessTokenResponseConverter { parameters ->	// ...	return OAuth2AccessTokenResponse.withToken("custom-token")		// ...		.build()}----======[#oauth2-client-{section-id}-access-token-response-errors]=== Customizing Error HandlingThe following example provides a starting point for customizing the conversion of Error parameters to an `OAuth2Error`:.Customize Access Token Error Handler[tabs]======Java::+[source,java,role="primary"]----OAuth2ErrorHttpMessageConverter errorConverter =	new OAuth2ErrorHttpMessageConverter();errorConverter.setErrorConverter(parameters -> {	// ...	return new OAuth2Error("custom-error", "custom description", "custom-uri");});OAuth2ErrorResponseErrorHandler errorHandler =	new OAuth2ErrorResponseErrorHandler();errorHandler.setErrorConverter(errorConverter);----Kotlin::+[source,kotlin,role="secondary"]----val errorConverter = OAuth2ErrorHttpMessageConverter()errorConverter.setErrorConverter { parameters ->	// ...	return OAuth2Error("custom-error", "custom description", "custom-uri")}val errorHandler = OAuth2ErrorResponseErrorHandler()errorHandler.setErrorConverter(errorConverter)----======
 |