Browse Source

OAuth2AuthorizeRequest supports attributes

Fixes gh-7341
Joe Grandja 6 years ago
parent
commit
a60446836b
22 changed files with 554 additions and 526 deletions
  1. 2 2
      config/src/main/java/org/springframework/security/config/annotation/web/reactive/ReactiveOAuth2ClientImportSelector.java
  2. 198 0
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/OAuth2AuthorizeRequest.java
  3. 4 4
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/OAuth2AuthorizedClientManager.java
  4. 8 8
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ReactiveOAuth2AuthorizedClientManager.java
  5. 36 4
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManager.java
  6. 25 17
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManager.java
  7. 0 130
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizeRequest.java
  8. 7 4
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/method/annotation/OAuth2AuthorizedClientArgumentResolver.java
  9. 29 17
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunction.java
  10. 24 6
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java
  11. 16 10
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/result/method/annotation/OAuth2AuthorizedClientArgumentResolver.java
  12. 0 112
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/ServerOAuth2AuthorizeRequest.java
  13. 29 30
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/OAuth2AuthorizeRequestTests.java
  14. 83 18
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManagerTests.java
  15. 57 28
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManagerTests.java
  16. 0 104
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizeRequestTests.java
  17. 3 2
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/method/annotation/OAuth2AuthorizedClientArgumentResolverTests.java
  18. 20 19
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunctionTests.java
  19. 4 2
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunctionTests.java
  20. 2 2
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/reactive/result/method/annotation/OAuth2AuthorizedClientArgumentResolverTests.java
  21. 6 6
      samples/boot/oauth2webclient-webflux/src/main/java/sample/config/WebClientConfig.java
  22. 1 1
      samples/boot/oauth2webclient/src/main/java/sample/config/WebClientConfig.java

+ 2 - 2
config/src/main/java/org/springframework/security/config/annotation/web/reactive/ReactiveOAuth2ClientImportSelector.java

@@ -26,7 +26,7 @@ import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClient
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.web.reactive.result.method.annotation.OAuth2AuthorizedClientArgumentResolver;
 import org.springframework.security.oauth2.client.web.reactive.result.method.annotation.OAuth2AuthorizedClientArgumentResolver;
 import org.springframework.security.oauth2.client.web.server.AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.client.web.server.AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository;
-import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.util.ClassUtils;
 import org.springframework.util.ClassUtils;
 import org.springframework.web.reactive.config.WebFluxConfigurer;
 import org.springframework.web.reactive.config.WebFluxConfigurer;
@@ -73,7 +73,7 @@ final class ReactiveOAuth2ClientImportSelector implements ImportSelector {
 								.clientCredentials()
 								.clientCredentials()
 								.password()
 								.password()
 								.build();
 								.build();
-				DefaultServerOAuth2AuthorizedClientManager authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
+				DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
 						this.clientRegistrationRepository, getAuthorizedClientRepository());
 						this.clientRegistrationRepository, getAuthorizedClientRepository());
 				authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 				authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 				configurer.addCustomResolver(new OAuth2AuthorizedClientArgumentResolver(authorizedClientManager));
 				configurer.addCustomResolver(new OAuth2AuthorizedClientArgumentResolver(authorizedClientManager));

+ 198 - 0
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/OAuth2AuthorizeRequest.java

@@ -0,0 +1,198 @@
+/*
+ * Copyright 2002-2019 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.security.oauth2.client;
+
+import org.springframework.lang.Nullable;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.client.registration.ClientRegistration;
+import org.springframework.util.Assert;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+
+/**
+ * Represents a request the {@link OAuth2AuthorizedClientManager} uses to
+ * {@link OAuth2AuthorizedClientManager#authorize(OAuth2AuthorizeRequest) authorize} (or re-authorize)
+ * the {@link ClientRegistration client} identified by the provided {@link #getClientRegistrationId() clientRegistrationId}.
+ *
+ * @author Joe Grandja
+ * @since 5.2
+ * @see OAuth2AuthorizedClientManager
+ */
+public final class OAuth2AuthorizeRequest {
+	private String clientRegistrationId;
+	private OAuth2AuthorizedClient authorizedClient;
+	private Authentication principal;
+	private Map<String, Object> attributes;
+
+	private OAuth2AuthorizeRequest() {
+	}
+
+	/**
+	 * Returns the identifier for the {@link ClientRegistration client registration}.
+	 *
+	 * @return the identifier for the client registration
+	 */
+	public String getClientRegistrationId() {
+		return this.clientRegistrationId;
+	}
+
+	/**
+	 * Returns the {@link OAuth2AuthorizedClient authorized client} or {@code null} if it was not provided.
+	 *
+	 * @return the {@link OAuth2AuthorizedClient} or {@code null} if it was not provided
+	 */
+	@Nullable
+	public OAuth2AuthorizedClient getAuthorizedClient() {
+		return this.authorizedClient;
+	}
+
+	/**
+	 * Returns the {@code Principal} (to be) associated to the authorized client.
+	 *
+	 * @return the {@code Principal} (to be) associated to the authorized client
+	 */
+	public Authentication getPrincipal() {
+		return this.principal;
+	}
+
+	/**
+	 * Returns the attributes associated to the request.
+	 *
+	 * @return a {@code Map} of the attributes associated to the request
+	 */
+	public Map<String, Object> getAttributes() {
+		return this.attributes;
+	}
+
+	/**
+	 * Returns the value of an attribute associated to the request or {@code null} if not available.
+	 *
+	 * @param name the name of the attribute
+	 * @param <T> the type of the attribute
+	 * @return the value of the attribute associated to the request
+	 */
+	@Nullable
+	@SuppressWarnings("unchecked")
+	public <T> T getAttribute(String name) {
+		return (T) this.getAttributes().get(name);
+	}
+
+	/**
+	 * Returns a new {@link Builder} initialized with the identifier for the {@link ClientRegistration client registration}.
+	 *
+	 * @param clientRegistrationId the identifier for the {@link ClientRegistration client registration}
+	 * @return the {@link Builder}
+	 */
+	public static Builder withClientRegistrationId(String clientRegistrationId) {
+		return new Builder(clientRegistrationId);
+	}
+
+	/**
+	 * Returns a new {@link Builder} initialized with the {@link OAuth2AuthorizedClient authorized client}.
+	 *
+	 * @param authorizedClient the {@link OAuth2AuthorizedClient authorized client}
+	 * @return the {@link Builder}
+	 */
+	public static Builder withAuthorizedClient(OAuth2AuthorizedClient authorizedClient) {
+		return new Builder(authorizedClient);
+	}
+
+	/**
+	 * A builder for {@link OAuth2AuthorizeRequest}.
+	 */
+	public static class Builder {
+		private String clientRegistrationId;
+		private OAuth2AuthorizedClient authorizedClient;
+		private Authentication principal;
+		private Map<String, Object> attributes;
+
+		private Builder(String clientRegistrationId) {
+			Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
+			this.clientRegistrationId = clientRegistrationId;
+		}
+
+		private Builder(OAuth2AuthorizedClient authorizedClient) {
+			Assert.notNull(authorizedClient, "authorizedClient cannot be null");
+			this.authorizedClient = authorizedClient;
+		}
+
+		/**
+		 * Sets the {@code Principal} (to be) associated to the authorized client.
+		 *
+		 * @param principal the {@code Principal} (to be) associated to the authorized client
+		 * @return the {@link Builder}
+		 */
+		public Builder principal(Authentication principal) {
+			this.principal = principal;
+			return this;
+		}
+
+		/**
+		 * Provides a {@link Consumer} access to the attributes associated to the request.
+		 *
+		 * @param attributesConsumer a {@link Consumer} of the attributes associated to the request
+		 * @return the {@link Builder}
+		 */
+		public Builder attributes(Consumer<Map<String, Object>> attributesConsumer) {
+			if (this.attributes == null) {
+				this.attributes = new HashMap<>();
+			}
+			attributesConsumer.accept(this.attributes);
+			return this;
+		}
+
+		/**
+		 * Sets an attribute associated to the request.
+		 *
+		 * @param name the name of the attribute
+		 * @param value the value of the attribute
+		 * @return the {@link Builder}
+		 */
+		public Builder attribute(String name, Object value) {
+			if (this.attributes == null) {
+				this.attributes = new HashMap<>();
+			}
+			this.attributes.put(name, value);
+			return this;
+		}
+
+		/**
+		 * Builds a new {@link OAuth2AuthorizeRequest}.
+		 *
+		 * @return a {@link OAuth2AuthorizeRequest}
+		 */
+		public OAuth2AuthorizeRequest build() {
+			Assert.notNull(this.principal, "principal cannot be null");
+			OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest();
+			if (this.authorizedClient != null) {
+				authorizeRequest.clientRegistrationId = this.authorizedClient.getClientRegistration().getRegistrationId();
+				authorizeRequest.authorizedClient = this.authorizedClient;
+			} else {
+				authorizeRequest.clientRegistrationId = this.clientRegistrationId;
+			}
+			authorizeRequest.principal = this.principal;
+			authorizeRequest.attributes = Collections.unmodifiableMap(
+					CollectionUtils.isEmpty(this.attributes) ?
+							Collections.emptyMap() : new LinkedHashMap<>(this.attributes));
+			return authorizeRequest;
+		}
+	}
+}

+ 4 - 4
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizedClientManager.java → oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/OAuth2AuthorizedClientManager.java

@@ -13,12 +13,11 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package org.springframework.security.oauth2.client.web;
+package org.springframework.security.oauth2.client;
 
 
 import org.springframework.lang.Nullable;
 import org.springframework.lang.Nullable;
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
+import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
 
 
 /**
 /**
  * Implementations of this interface are responsible for the overall management
  * Implementations of this interface are responsible for the overall management
@@ -30,13 +29,14 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
  *  <li>Authorizing (or re-authorizing) an OAuth 2.0 Client
  *  <li>Authorizing (or re-authorizing) an OAuth 2.0 Client
  *  	by leveraging an {@link OAuth2AuthorizedClientProvider}(s).</li>
  *  	by leveraging an {@link OAuth2AuthorizedClientProvider}(s).</li>
  *  <li>Managing the persistence of an {@link OAuth2AuthorizedClient} between requests,
  *  <li>Managing the persistence of an {@link OAuth2AuthorizedClient} between requests,
- *  	typically using an {@link OAuth2AuthorizedClientRepository}.</li>
+ *  	typically using an {@link OAuth2AuthorizedClientService} OR {@link OAuth2AuthorizedClientRepository}.</li>
  * </ol>
  * </ol>
  *
  *
  * @author Joe Grandja
  * @author Joe Grandja
  * @since 5.2
  * @since 5.2
  * @see OAuth2AuthorizedClient
  * @see OAuth2AuthorizedClient
  * @see OAuth2AuthorizedClientProvider
  * @see OAuth2AuthorizedClientProvider
+ * @see OAuth2AuthorizedClientService
  * @see OAuth2AuthorizedClientRepository
  * @see OAuth2AuthorizedClientRepository
  */
  */
 public interface OAuth2AuthorizedClientManager {
 public interface OAuth2AuthorizedClientManager {

+ 8 - 8
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/ServerOAuth2AuthorizedClientManager.java → oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ReactiveOAuth2AuthorizedClientManager.java

@@ -13,11 +13,10 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package org.springframework.security.oauth2.client.web.server;
+package org.springframework.security.oauth2.client;
 
 
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
-import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
+import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import reactor.core.publisher.Mono;
 import reactor.core.publisher.Mono;
 
 
 /**
 /**
@@ -30,26 +29,27 @@ import reactor.core.publisher.Mono;
  *  <li>Authorizing (or re-authorizing) an OAuth 2.0 Client
  *  <li>Authorizing (or re-authorizing) an OAuth 2.0 Client
  *  	by leveraging a {@link ReactiveOAuth2AuthorizedClientProvider}(s).</li>
  *  	by leveraging a {@link ReactiveOAuth2AuthorizedClientProvider}(s).</li>
  *  <li>Managing the persistence of an {@link OAuth2AuthorizedClient} between requests,
  *  <li>Managing the persistence of an {@link OAuth2AuthorizedClient} between requests,
- *  	typically using an {@link ServerOAuth2AuthorizedClientRepository}.</li>
+ *  	typically using a {@link ReactiveOAuth2AuthorizedClientService} OR {@link ServerOAuth2AuthorizedClientRepository}.</li>
  * </ol>
  * </ol>
  *
  *
  * @author Joe Grandja
  * @author Joe Grandja
  * @since 5.2
  * @since 5.2
  * @see OAuth2AuthorizedClient
  * @see OAuth2AuthorizedClient
  * @see ReactiveOAuth2AuthorizedClientProvider
  * @see ReactiveOAuth2AuthorizedClientProvider
+ * @see ReactiveOAuth2AuthorizedClientService
  * @see ServerOAuth2AuthorizedClientRepository
  * @see ServerOAuth2AuthorizedClientRepository
  */
  */
-public interface ServerOAuth2AuthorizedClientManager {
+public interface ReactiveOAuth2AuthorizedClientManager {
 
 
 	/**
 	/**
 	 * Attempt to authorize or re-authorize (if required) the {@link ClientRegistration client}
 	 * Attempt to authorize or re-authorize (if required) the {@link ClientRegistration client}
-	 * identified by the provided {@link ServerOAuth2AuthorizeRequest#getClientRegistrationId() clientRegistrationId}.
+	 * identified by the provided {@link OAuth2AuthorizeRequest#getClientRegistrationId() clientRegistrationId}.
 	 * Implementations must return an empty {@code Mono} if authorization is not supported for the specified client,
 	 * Implementations must return an empty {@code Mono} if authorization is not supported for the specified client,
 	 * e.g. the associated {@link ReactiveOAuth2AuthorizedClientProvider}(s) does not support
 	 * e.g. the associated {@link ReactiveOAuth2AuthorizedClientProvider}(s) does not support
 	 * the {@link ClientRegistration#getAuthorizationGrantType() authorization grant} type configured for the client.
 	 * the {@link ClientRegistration#getAuthorizationGrantType() authorization grant} type configured for the client.
 	 *
 	 *
 	 * <p>
 	 * <p>
-	 * In the case of re-authorization, implementations must return the provided {@link ServerOAuth2AuthorizeRequest#getAuthorizedClient() authorized client}
+	 * In the case of re-authorization, implementations must return the provided {@link OAuth2AuthorizeRequest#getAuthorizedClient() authorized client}
 	 * if re-authorization is not supported for the client OR is not required,
 	 * if re-authorization is not supported for the client OR is not required,
 	 * e.g. a {@link OAuth2AuthorizedClient#getRefreshToken() refresh token} is not available OR
 	 * e.g. a {@link OAuth2AuthorizedClient#getRefreshToken() refresh token} is not available OR
 	 * the {@link OAuth2AuthorizedClient#getAccessToken() access token} is not expired.
 	 * the {@link OAuth2AuthorizedClient#getAccessToken() access token} is not expired.
@@ -57,6 +57,6 @@ public interface ServerOAuth2AuthorizedClientManager {
 	 * @param authorizeRequest the authorize request
 	 * @param authorizeRequest the authorize request
 	 * @return the {@link OAuth2AuthorizedClient} or an empty {@code Mono} if authorization is not supported for the specified client
 	 * @return the {@link OAuth2AuthorizedClient} or an empty {@code Mono} if authorization is not supported for the specified client
 	 */
 	 */
-	Mono<OAuth2AuthorizedClient> authorize(ServerOAuth2AuthorizeRequest authorizeRequest);
+	Mono<OAuth2AuthorizedClient> authorize(OAuth2AuthorizeRequest authorizeRequest);
 
 
 }
 }

+ 36 - 4
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManager.java

@@ -18,16 +18,21 @@ package org.springframework.security.oauth2.client.web;
 import org.springframework.lang.Nullable;
 import org.springframework.lang.Nullable;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
 import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
+import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
+import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponse;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.function.Function;
@@ -68,8 +73,11 @@ public final class DefaultOAuth2AuthorizedClientManager implements OAuth2Authori
 		String clientRegistrationId = authorizeRequest.getClientRegistrationId();
 		String clientRegistrationId = authorizeRequest.getClientRegistrationId();
 		OAuth2AuthorizedClient authorizedClient = authorizeRequest.getAuthorizedClient();
 		OAuth2AuthorizedClient authorizedClient = authorizeRequest.getAuthorizedClient();
 		Authentication principal = authorizeRequest.getPrincipal();
 		Authentication principal = authorizeRequest.getPrincipal();
-		HttpServletRequest servletRequest = authorizeRequest.getServletRequest();
-		HttpServletResponse servletResponse = authorizeRequest.getServletResponse();
+
+		HttpServletRequest servletRequest = getHttpServletRequestOrDefault(authorizeRequest.getAttributes());
+		Assert.notNull(servletRequest, "servletRequest cannot be null");
+		HttpServletResponse servletResponse = getHttpServletResponseOrDefault(authorizeRequest.getAttributes());
+		Assert.notNull(servletResponse, "servletResponse cannot be null");
 
 
 		OAuth2AuthorizationContext.Builder contextBuilder;
 		OAuth2AuthorizationContext.Builder contextBuilder;
 		if (authorizedClient != null) {
 		if (authorizedClient != null) {
@@ -104,6 +112,28 @@ public final class DefaultOAuth2AuthorizedClientManager implements OAuth2Authori
 		return authorizedClient;
 		return authorizedClient;
 	}
 	}
 
 
+	private static HttpServletRequest getHttpServletRequestOrDefault(Map<String, Object> attributes) {
+		HttpServletRequest servletRequest = (HttpServletRequest) attributes.get(HttpServletRequest.class.getName());
+		if (servletRequest == null) {
+			ServletRequestAttributes context = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+			if (context != null) {
+				servletRequest = context.getRequest();
+			}
+		}
+		return servletRequest;
+	}
+
+	private static HttpServletResponse getHttpServletResponseOrDefault(Map<String, Object> attributes) {
+		HttpServletResponse servletResponse = (HttpServletResponse) attributes.get(HttpServletResponse.class.getName());
+		if (servletResponse == null) {
+			ServletRequestAttributes context = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+			if (context != null) {
+				servletResponse = context.getResponse();
+			}
+		}
+		return servletResponse;
+	}
+
 	/**
 	/**
 	 * Sets the {@link OAuth2AuthorizedClientProvider} used for authorizing (or re-authorizing) an OAuth 2.0 Client.
 	 * Sets the {@link OAuth2AuthorizedClientProvider} used for authorizing (or re-authorizing) an OAuth 2.0 Client.
 	 *
 	 *
@@ -133,9 +163,11 @@ public final class DefaultOAuth2AuthorizedClientManager implements OAuth2Authori
 
 
 		@Override
 		@Override
 		public Map<String, Object> apply(OAuth2AuthorizeRequest authorizeRequest) {
 		public Map<String, Object> apply(OAuth2AuthorizeRequest authorizeRequest) {
-			Map<String, Object> contextAttributes = new HashMap<>();
-			String scope = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.SCOPE);
+			Map<String, Object> contextAttributes = Collections.emptyMap();
+			HttpServletRequest servletRequest = getHttpServletRequestOrDefault(authorizeRequest.getAttributes());
+			String scope = servletRequest.getParameter(OAuth2ParameterNames.SCOPE);
 			if (StringUtils.hasText(scope)) {
 			if (StringUtils.hasText(scope)) {
+				contextAttributes = new HashMap<>();
 				contextAttributes.put(OAuth2AuthorizationContext.REQUEST_SCOPE_ATTRIBUTE_NAME,
 				contextAttributes.put(OAuth2AuthorizationContext.REQUEST_SCOPE_ATTRIBUTE_NAME,
 						StringUtils.delimitedListToStringArray(scope, " "));
 						StringUtils.delimitedListToStringArray(scope, " "));
 			}
 			}

+ 25 - 17
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/DefaultServerOAuth2AuthorizedClientManager.java → oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManager.java

@@ -13,45 +13,49 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package org.springframework.security.oauth2.client.web.server;
+package org.springframework.security.oauth2.client.web;
 
 
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
 import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
+import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
+import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
+import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
 import org.springframework.web.server.ServerWebExchange;
 import org.springframework.web.server.ServerWebExchange;
 import reactor.core.publisher.Mono;
 import reactor.core.publisher.Mono;
 
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.function.Function;
 
 
 /**
 /**
- * The default implementation of a {@link ServerOAuth2AuthorizedClientManager}.
+ * The default implementation of a {@link ReactiveOAuth2AuthorizedClientManager}.
  *
  *
  * @author Joe Grandja
  * @author Joe Grandja
  * @since 5.2
  * @since 5.2
- * @see ServerOAuth2AuthorizedClientManager
+ * @see ReactiveOAuth2AuthorizedClientManager
  * @see ReactiveOAuth2AuthorizedClientProvider
  * @see ReactiveOAuth2AuthorizedClientProvider
  */
  */
-public final class DefaultServerOAuth2AuthorizedClientManager implements ServerOAuth2AuthorizedClientManager {
+public final class DefaultReactiveOAuth2AuthorizedClientManager implements ReactiveOAuth2AuthorizedClientManager {
 	private final ReactiveClientRegistrationRepository clientRegistrationRepository;
 	private final ReactiveClientRegistrationRepository clientRegistrationRepository;
 	private final ServerOAuth2AuthorizedClientRepository authorizedClientRepository;
 	private final ServerOAuth2AuthorizedClientRepository authorizedClientRepository;
 	private ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = context -> Mono.empty();
 	private ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = context -> Mono.empty();
-	private Function<ServerOAuth2AuthorizeRequest, Mono<Map<String, Object>>> contextAttributesMapper = new DefaultContextAttributesMapper();
+	private Function<OAuth2AuthorizeRequest, Mono<Map<String, Object>>> contextAttributesMapper = new DefaultContextAttributesMapper();
 
 
 	/**
 	/**
-	 * Constructs a {@code DefaultServerOAuth2AuthorizedClientManager} using the provided parameters.
+	 * Constructs a {@code DefaultReactiveOAuth2AuthorizedClientManager} using the provided parameters.
 	 *
 	 *
 	 * @param clientRegistrationRepository the repository of client registrations
 	 * @param clientRegistrationRepository the repository of client registrations
 	 * @param authorizedClientRepository the repository of authorized clients
 	 * @param authorizedClientRepository the repository of authorized clients
 	 */
 	 */
-	public DefaultServerOAuth2AuthorizedClientManager(ReactiveClientRegistrationRepository clientRegistrationRepository,
+	public DefaultReactiveOAuth2AuthorizedClientManager(ReactiveClientRegistrationRepository clientRegistrationRepository,
 														ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
 														ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
 		Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null");
 		Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null");
 		Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null");
 		Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null");
@@ -60,12 +64,14 @@ public final class DefaultServerOAuth2AuthorizedClientManager implements ServerO
 	}
 	}
 
 
 	@Override
 	@Override
-	public Mono<OAuth2AuthorizedClient> authorize(ServerOAuth2AuthorizeRequest authorizeRequest) {
+	public Mono<OAuth2AuthorizedClient> authorize(OAuth2AuthorizeRequest authorizeRequest) {
 		Assert.notNull(authorizeRequest, "authorizeRequest cannot be null");
 		Assert.notNull(authorizeRequest, "authorizeRequest cannot be null");
 
 
 		String clientRegistrationId = authorizeRequest.getClientRegistrationId();
 		String clientRegistrationId = authorizeRequest.getClientRegistrationId();
 		Authentication principal = authorizeRequest.getPrincipal();
 		Authentication principal = authorizeRequest.getPrincipal();
-		ServerWebExchange serverWebExchange = authorizeRequest.getServerWebExchange();
+
+		ServerWebExchange serverWebExchange = authorizeRequest.getAttribute(ServerWebExchange.class.getName());
+		Assert.notNull(serverWebExchange, "serverWebExchange cannot be null");
 
 
 		return Mono.justOrEmpty(authorizeRequest.getAuthorizedClient())
 		return Mono.justOrEmpty(authorizeRequest.getAuthorizedClient())
 				.switchIfEmpty(Mono.defer(() ->
 				.switchIfEmpty(Mono.defer(() ->
@@ -94,7 +100,7 @@ public final class DefaultServerOAuth2AuthorizedClientManager implements ServerO
 				));
 				));
 	}
 	}
 
 
-	private Mono<OAuth2AuthorizationContext> authorizationContext(ServerOAuth2AuthorizeRequest authorizeRequest,
+	private Mono<OAuth2AuthorizationContext> authorizationContext(OAuth2AuthorizeRequest authorizeRequest,
 																	OAuth2AuthorizedClient authorizedClient) {
 																	OAuth2AuthorizedClient authorizedClient) {
 		return Mono.just(authorizeRequest)
 		return Mono.just(authorizeRequest)
 				.flatMap(this.contextAttributesMapper::apply)
 				.flatMap(this.contextAttributesMapper::apply)
@@ -104,7 +110,7 @@ public final class DefaultServerOAuth2AuthorizedClientManager implements ServerO
 						.build());
 						.build());
 	}
 	}
 
 
-	private Mono<OAuth2AuthorizationContext> authorizationContext(ServerOAuth2AuthorizeRequest authorizeRequest,
+	private Mono<OAuth2AuthorizationContext> authorizationContext(OAuth2AuthorizeRequest authorizeRequest,
 																	ClientRegistration clientRegistration) {
 																	ClientRegistration clientRegistration) {
 		return Mono.just(authorizeRequest)
 		return Mono.just(authorizeRequest)
 				.flatMap(this.contextAttributesMapper::apply)
 				.flatMap(this.contextAttributesMapper::apply)
@@ -125,13 +131,13 @@ public final class DefaultServerOAuth2AuthorizedClientManager implements ServerO
 	}
 	}
 
 
 	/**
 	/**
-	 * Sets the {@code Function} used for mapping attribute(s) from the {@link ServerOAuth2AuthorizeRequest} to a {@code Map} of attributes
+	 * Sets the {@code Function} used for mapping attribute(s) from the {@link OAuth2AuthorizeRequest} to a {@code Map} of attributes
 	 * to be associated to the {@link OAuth2AuthorizationContext#getAttributes() authorization context}.
 	 * to be associated to the {@link OAuth2AuthorizationContext#getAttributes() authorization context}.
 	 *
 	 *
 	 * @param contextAttributesMapper the {@code Function} used for supplying the {@code Map} of attributes
 	 * @param contextAttributesMapper the {@code Function} used for supplying the {@code Map} of attributes
 	 *                                   to the {@link OAuth2AuthorizationContext#getAttributes() authorization context}
 	 *                                   to the {@link OAuth2AuthorizationContext#getAttributes() authorization context}
 	 */
 	 */
-	public void setContextAttributesMapper(Function<ServerOAuth2AuthorizeRequest, Mono<Map<String, Object>>> contextAttributesMapper) {
+	public void setContextAttributesMapper(Function<OAuth2AuthorizeRequest, Mono<Map<String, Object>>> contextAttributesMapper) {
 		Assert.notNull(contextAttributesMapper, "contextAttributesMapper cannot be null");
 		Assert.notNull(contextAttributesMapper, "contextAttributesMapper cannot be null");
 		this.contextAttributesMapper = contextAttributesMapper;
 		this.contextAttributesMapper = contextAttributesMapper;
 	}
 	}
@@ -139,13 +145,15 @@ public final class DefaultServerOAuth2AuthorizedClientManager implements ServerO
 	/**
 	/**
 	 * The default implementation of the {@link #setContextAttributesMapper(Function) contextAttributesMapper}.
 	 * The default implementation of the {@link #setContextAttributesMapper(Function) contextAttributesMapper}.
 	 */
 	 */
-	public static class DefaultContextAttributesMapper implements Function<ServerOAuth2AuthorizeRequest, Mono<Map<String, Object>>> {
+	public static class DefaultContextAttributesMapper implements Function<OAuth2AuthorizeRequest, Mono<Map<String, Object>>> {
 
 
 		@Override
 		@Override
-		public Mono<Map<String, Object>> apply(ServerOAuth2AuthorizeRequest authorizeRequest) {
-			Map<String, Object> contextAttributes = new HashMap<>();
-			String scope = authorizeRequest.getServerWebExchange().getRequest().getQueryParams().getFirst(OAuth2ParameterNames.SCOPE);
+		public Mono<Map<String, Object>> apply(OAuth2AuthorizeRequest authorizeRequest) {
+			Map<String, Object> contextAttributes = Collections.emptyMap();
+			ServerWebExchange serverWebExchange = authorizeRequest.getAttribute(ServerWebExchange.class.getName());
+			String scope = serverWebExchange.getRequest().getQueryParams().getFirst(OAuth2ParameterNames.SCOPE);
 			if (StringUtils.hasText(scope)) {
 			if (StringUtils.hasText(scope)) {
+				contextAttributes = new HashMap<>();
 				contextAttributes.put(OAuth2AuthorizationContext.REQUEST_SCOPE_ATTRIBUTE_NAME,
 				contextAttributes.put(OAuth2AuthorizationContext.REQUEST_SCOPE_ATTRIBUTE_NAME,
 						StringUtils.delimitedListToStringArray(scope, " "));
 						StringUtils.delimitedListToStringArray(scope, " "));
 			}
 			}

+ 0 - 130
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizeRequest.java

@@ -1,130 +0,0 @@
-/*
- * Copyright 2002-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.security.oauth2.client.web;
-
-import org.springframework.lang.Nullable;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.util.Assert;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Represents a request the {@link OAuth2AuthorizedClientManager} uses to
- * {@link OAuth2AuthorizedClientManager#authorize(OAuth2AuthorizeRequest) authorize} (or re-authorize)
- * the {@link ClientRegistration client} identified by the provided {@link #getClientRegistrationId() clientRegistrationId}.
- *
- * @author Joe Grandja
- * @since 5.2
- * @see OAuth2AuthorizedClientManager
- */
-public class OAuth2AuthorizeRequest {
-	private final String clientRegistrationId;
-	private final OAuth2AuthorizedClient authorizedClient;
-	private final Authentication principal;
-	private final HttpServletRequest servletRequest;
-	private final HttpServletResponse servletResponse;
-
-	/**
-	 * Constructs an {@code OAuth2AuthorizeRequest} using the provided parameters.
-	 *
-	 * @param clientRegistrationId the identifier for the {@link ClientRegistration client registration}
-	 * @param principal the {@code Principal} (to be) associated to the authorized client
-	 * @param servletRequest the {@code HttpServletRequest}
-	 * @param servletResponse the {@code HttpServletResponse}
-	 */
-	public OAuth2AuthorizeRequest(String clientRegistrationId, Authentication principal,
-									HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
-		Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
-		Assert.notNull(principal, "principal cannot be null");
-		Assert.notNull(servletRequest, "servletRequest cannot be null");
-		Assert.notNull(servletResponse, "servletResponse cannot be null");
-		this.clientRegistrationId = clientRegistrationId;
-		this.authorizedClient = null;
-		this.principal = principal;
-		this.servletRequest = servletRequest;
-		this.servletResponse = servletResponse;
-	}
-
-	/**
-	 * Constructs an {@code OAuth2AuthorizeRequest} using the provided parameters.
-	 *
-	 * @param authorizedClient the {@link OAuth2AuthorizedClient authorized client}
-	 * @param principal the {@code Principal} associated to the authorized client
-	 * @param servletRequest the {@code HttpServletRequest}
-	 * @param servletResponse the {@code HttpServletResponse}
-	 */
-	public OAuth2AuthorizeRequest(OAuth2AuthorizedClient authorizedClient, Authentication principal,
-									HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
-		Assert.notNull(authorizedClient, "authorizedClient cannot be null");
-		Assert.notNull(principal, "principal cannot be null");
-		Assert.notNull(servletRequest, "servletRequest cannot be null");
-		Assert.notNull(servletResponse, "servletResponse cannot be null");
-		this.clientRegistrationId = authorizedClient.getClientRegistration().getRegistrationId();
-		this.authorizedClient = authorizedClient;
-		this.principal = principal;
-		this.servletRequest = servletRequest;
-		this.servletResponse = servletResponse;
-	}
-
-	/**
-	 * Returns the identifier for the {@link ClientRegistration client registration}.
-	 *
-	 * @return the identifier for the client registration
-	 */
-	public String getClientRegistrationId() {
-		return this.clientRegistrationId;
-	}
-
-	/**
-	 * Returns the {@link OAuth2AuthorizedClient authorized client} or {@code null} if it was not provided.
-	 *
-	 * @return the {@link OAuth2AuthorizedClient} or {@code null} if it was not provided
-	 */
-	@Nullable
-	public OAuth2AuthorizedClient getAuthorizedClient() {
-		return this.authorizedClient;
-	}
-
-	/**
-	 * Returns the {@code Principal} (to be) associated to the authorized client.
-	 *
-	 * @return the {@code Principal} (to be) associated to the authorized client
-	 */
-	public Authentication getPrincipal() {
-		return this.principal;
-	}
-
-	/**
-	 * Returns the {@code HttpServletRequest}.
-	 *
-	 * @return the {@code HttpServletRequest}
-	 */
-	public HttpServletRequest getServletRequest() {
-		return this.servletRequest;
-	}
-
-	/**
-	 * Returns the {@code HttpServletResponse}.
-	 *
-	 * @return the {@code HttpServletResponse}
-	 */
-	public HttpServletResponse getServletResponse() {
-		return this.servletResponse;
-	}
-}

+ 7 - 4
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/method/annotation/OAuth2AuthorizedClientArgumentResolver.java

@@ -33,8 +33,8 @@ import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResp
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
-import org.springframework.security.oauth2.client.web.OAuth2AuthorizeRequest;
-import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
+import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
@@ -143,8 +143,11 @@ public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMeth
 		HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
 		HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
 		HttpServletResponse servletResponse = webRequest.getNativeResponse(HttpServletResponse.class);
 		HttpServletResponse servletResponse = webRequest.getNativeResponse(HttpServletResponse.class);
 
 
-		OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
-				clientRegistrationId, principal, servletRequest, servletResponse);
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistrationId)
+				.principal(principal)
+				.attribute(HttpServletRequest.class.getName(), servletRequest)
+				.attribute(HttpServletResponse.class.getName(), servletResponse)
+				.build();
 
 
 		return this.authorizedClientManager.authorize(authorizeRequest);
 		return this.authorizedClientManager.authorize(authorizeRequest);
 	}
 	}

+ 29 - 17
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunction.java

@@ -22,7 +22,9 @@ import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.context.ReactiveSecurityContextHolder;
 import org.springframework.security.core.context.ReactiveSecurityContextHolder;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.oauth2.client.ClientCredentialsReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.ClientCredentialsReactiveOAuth2AuthorizedClientProvider;
+import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
+import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
 import org.springframework.security.oauth2.client.RefreshTokenReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.RefreshTokenReactiveOAuth2AuthorizedClientProvider;
@@ -31,9 +33,7 @@ import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentia
 import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
-import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
-import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizeRequest;
-import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.web.reactive.function.client.ClientRequest;
 import org.springframework.web.reactive.function.client.ClientRequest;
@@ -75,7 +75,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
 	private static final AnonymousAuthenticationToken ANONYMOUS_USER_TOKEN = new AnonymousAuthenticationToken("anonymous", "anonymousUser",
 	private static final AnonymousAuthenticationToken ANONYMOUS_USER_TOKEN = new AnonymousAuthenticationToken("anonymous", "anonymousUser",
 			AuthorityUtils.createAuthorityList("ROLE_USER"));
 			AuthorityUtils.createAuthorityList("ROLE_USER"));
 
 
-	private ServerOAuth2AuthorizedClientManager authorizedClientManager;
+	private ReactiveOAuth2AuthorizedClientManager authorizedClientManager;
 
 
 	private boolean defaultAuthorizedClientManager;
 	private boolean defaultAuthorizedClientManager;
 
 
@@ -94,9 +94,9 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
 	 * Constructs a {@code ServerOAuth2AuthorizedClientExchangeFilterFunction} using the provided parameters.
 	 * Constructs a {@code ServerOAuth2AuthorizedClientExchangeFilterFunction} using the provided parameters.
 	 *
 	 *
 	 * @since 5.2
 	 * @since 5.2
-	 * @param authorizedClientManager the {@link ServerOAuth2AuthorizedClientManager} which manages the authorized client(s)
+	 * @param authorizedClientManager the {@link ReactiveOAuth2AuthorizedClientManager} which manages the authorized client(s)
 	 */
 	 */
-	public ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager authorizedClientManager) {
+	public ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
 		Assert.notNull(authorizedClientManager, "authorizedClientManager cannot be null");
 		Assert.notNull(authorizedClientManager, "authorizedClientManager cannot be null");
 		this.authorizedClientManager = authorizedClientManager;
 		this.authorizedClientManager = authorizedClientManager;
 	}
 	}
@@ -113,7 +113,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
 		this.defaultAuthorizedClientManager = true;
 		this.defaultAuthorizedClientManager = true;
 	}
 	}
 
 
-	private static ServerOAuth2AuthorizedClientManager createDefaultAuthorizedClientManager(
+	private static ReactiveOAuth2AuthorizedClientManager createDefaultAuthorizedClientManager(
 			ReactiveClientRegistrationRepository clientRegistrationRepository,
 			ReactiveClientRegistrationRepository clientRegistrationRepository,
 			ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
 			ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
 
 
@@ -124,7 +124,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
 						.clientCredentials()
 						.clientCredentials()
 						.password()
 						.password()
 						.build();
 						.build();
-		DefaultServerOAuth2AuthorizedClientManager authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
+		DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
 				clientRegistrationRepository, authorizedClientRepository);
 				clientRegistrationRepository, authorizedClientRepository);
 		authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 		authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 
 
@@ -241,10 +241,10 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
 	/**
 	/**
 	 * Sets the {@link ReactiveOAuth2AccessTokenResponseClient} used for getting an {@link OAuth2AuthorizedClient} for the client_credentials grant.
 	 * Sets the {@link ReactiveOAuth2AccessTokenResponseClient} used for getting an {@link OAuth2AuthorizedClient} for the client_credentials grant.
 	 *
 	 *
-	 * @deprecated Use {@link #ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager)} instead.
+	 * @deprecated Use {@link #ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)} instead.
 	 * 				Create an instance of {@link ClientCredentialsReactiveOAuth2AuthorizedClientProvider} configured with a
 	 * 				Create an instance of {@link ClientCredentialsReactiveOAuth2AuthorizedClientProvider} configured with a
 	 * 				{@link ClientCredentialsReactiveOAuth2AuthorizedClientProvider#setAccessTokenResponseClient(ReactiveOAuth2AccessTokenResponseClient) WebClientReactiveClientCredentialsTokenResponseClient}
 	 * 				{@link ClientCredentialsReactiveOAuth2AuthorizedClientProvider#setAccessTokenResponseClient(ReactiveOAuth2AccessTokenResponseClient) WebClientReactiveClientCredentialsTokenResponseClient}
-	 * 				(or a custom one) and than supply it to {@link DefaultServerOAuth2AuthorizedClientManager#setAuthorizedClientProvider(ReactiveOAuth2AuthorizedClientProvider) DefaultOAuth2AuthorizedClientManager}.
+	 * 				(or a custom one) and than supply it to {@link DefaultReactiveOAuth2AuthorizedClientManager#setAuthorizedClientProvider(ReactiveOAuth2AuthorizedClientProvider) DefaultReactiveOAuth2AuthorizedClientManager}.
 	 *
 	 *
 	 * @param clientCredentialsTokenResponseClient the client to use
 	 * @param clientCredentialsTokenResponseClient the client to use
 	 */
 	 */
@@ -252,7 +252,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
 	public void setClientCredentialsTokenResponseClient(
 	public void setClientCredentialsTokenResponseClient(
 			ReactiveOAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsTokenResponseClient) {
 			ReactiveOAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsTokenResponseClient) {
 		Assert.notNull(clientCredentialsTokenResponseClient, "clientCredentialsTokenResponseClient cannot be null");
 		Assert.notNull(clientCredentialsTokenResponseClient, "clientCredentialsTokenResponseClient cannot be null");
-		Assert.state(this.defaultAuthorizedClientManager, "The client cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager)\". " +
+		Assert.state(this.defaultAuthorizedClientManager, "The client cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)\". " +
 				"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
 				"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
 		this.clientCredentialsTokenResponseClient = clientCredentialsTokenResponseClient;
 		this.clientCredentialsTokenResponseClient = clientCredentialsTokenResponseClient;
 		updateDefaultAuthorizedClientManager();
 		updateDefaultAuthorizedClientManager();
@@ -266,7 +266,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
 						.clientCredentials(this::updateClientCredentialsProvider)
 						.clientCredentials(this::updateClientCredentialsProvider)
 						.password(configurer -> configurer.clockSkew(this.accessTokenExpiresSkew))
 						.password(configurer -> configurer.clockSkew(this.accessTokenExpiresSkew))
 						.build();
 						.build();
-		((DefaultServerOAuth2AuthorizedClientManager) this.authorizedClientManager).setAuthorizedClientProvider(authorizedClientProvider);
+		((DefaultReactiveOAuth2AuthorizedClientManager) this.authorizedClientManager).setAuthorizedClientProvider(authorizedClientProvider);
 	}
 	}
 
 
 	private void updateClientCredentialsProvider(ReactiveOAuth2AuthorizedClientProviderBuilder.ClientCredentialsGrantBuilder builder) {
 	private void updateClientCredentialsProvider(ReactiveOAuth2AuthorizedClientProviderBuilder.ClientCredentialsGrantBuilder builder) {
@@ -289,7 +289,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
 	@Deprecated
 	@Deprecated
 	public void setAccessTokenExpiresSkew(Duration accessTokenExpiresSkew) {
 	public void setAccessTokenExpiresSkew(Duration accessTokenExpiresSkew) {
 		Assert.notNull(accessTokenExpiresSkew, "accessTokenExpiresSkew cannot be null");
 		Assert.notNull(accessTokenExpiresSkew, "accessTokenExpiresSkew cannot be null");
-		Assert.state(this.defaultAuthorizedClientManager, "The accessTokenExpiresSkew cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager)\". " +
+		Assert.state(this.defaultAuthorizedClientManager, "The accessTokenExpiresSkew cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)\". " +
 				"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
 				"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
 		this.accessTokenExpiresSkew = accessTokenExpiresSkew;
 		this.accessTokenExpiresSkew = accessTokenExpiresSkew;
 		updateDefaultAuthorizedClientManager();
 		updateDefaultAuthorizedClientManager();
@@ -312,7 +312,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
 						reauthorizeRequest(request, authorizedClient).flatMap(this.authorizedClientManager::authorize));
 						reauthorizeRequest(request, authorizedClient).flatMap(this.authorizedClientManager::authorize));
 	}
 	}
 
 
-	private Mono<ServerOAuth2AuthorizeRequest> authorizeRequest(ClientRequest request) {
+	private Mono<OAuth2AuthorizeRequest> authorizeRequest(ClientRequest request) {
 		Mono<Authentication> authentication = currentAuthentication();
 		Mono<Authentication> authentication = currentAuthentication();
 
 
 		Mono<String> clientRegistrationId = Mono.justOrEmpty(clientRegistrationId(request))
 		Mono<String> clientRegistrationId = Mono.justOrEmpty(clientRegistrationId(request))
@@ -325,10 +325,16 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
 				.defaultIfEmpty(Optional.empty());
 				.defaultIfEmpty(Optional.empty());
 
 
 		return Mono.zip(clientRegistrationId, authentication, serverWebExchange)
 		return Mono.zip(clientRegistrationId, authentication, serverWebExchange)
-				.map(t3 -> new ServerOAuth2AuthorizeRequest(t3.getT1(), t3.getT2(), t3.getT3().orElse(null)));
+				.map(t3 -> {
+					OAuth2AuthorizeRequest.Builder builder = OAuth2AuthorizeRequest.withClientRegistrationId(t3.getT1()).principal(t3.getT2());
+					if (t3.getT3().isPresent()) {
+						builder.attribute(ServerWebExchange.class.getName(), t3.getT3().get());
+					}
+					return builder.build();
+				});
 	}
 	}
 
 
-	private Mono<ServerOAuth2AuthorizeRequest> reauthorizeRequest(ClientRequest request, OAuth2AuthorizedClient authorizedClient) {
+	private Mono<OAuth2AuthorizeRequest> reauthorizeRequest(ClientRequest request, OAuth2AuthorizedClient authorizedClient) {
 		Mono<Authentication> authentication = currentAuthentication();
 		Mono<Authentication> authentication = currentAuthentication();
 
 
 		Mono<Optional<ServerWebExchange>> serverWebExchange = Mono.justOrEmpty(serverWebExchange(request))
 		Mono<Optional<ServerWebExchange>> serverWebExchange = Mono.justOrEmpty(serverWebExchange(request))
@@ -337,7 +343,13 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
 				.defaultIfEmpty(Optional.empty());
 				.defaultIfEmpty(Optional.empty());
 
 
 		return Mono.zip(authentication, serverWebExchange)
 		return Mono.zip(authentication, serverWebExchange)
-				.map(t2 -> new ServerOAuth2AuthorizeRequest(authorizedClient, t2.getT1(), t2.getT2().orElse(null)));
+				.map(t2 -> {
+					OAuth2AuthorizeRequest.Builder builder = OAuth2AuthorizeRequest.withAuthorizedClient(authorizedClient).principal(t2.getT1());
+					if (t2.getT2().isPresent()) {
+						builder.attribute(ServerWebExchange.class.getName(), t2.getT2().get());
+					}
+					return builder.build();
+				});
 	}
 	}
 
 
 	private Mono<Authentication> currentAuthentication() {
 	private Mono<Authentication> currentAuthentication() {

+ 24 - 6
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java

@@ -26,7 +26,9 @@ import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.oauth2.client.ClientCredentialsOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.ClientCredentialsOAuth2AuthorizedClientProvider;
+import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
+import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
 import org.springframework.security.oauth2.client.RefreshTokenOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.RefreshTokenOAuth2AuthorizedClientProvider;
@@ -36,8 +38,6 @@ import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentia
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
-import org.springframework.security.oauth2.client.web.OAuth2AuthorizeRequest;
-import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.RequestContextHolder;
@@ -451,8 +451,17 @@ public final class ServletOAuth2AuthorizedClientExchangeFilterFunction
 		}
 		}
 		HttpServletRequest servletRequest = getRequest(attrs);
 		HttpServletRequest servletRequest = getRequest(attrs);
 		HttpServletResponse servletResponse = getResponse(attrs);
 		HttpServletResponse servletResponse = getResponse(attrs);
-		OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
-				clientRegistrationId, authentication, servletRequest, servletResponse);
+
+		OAuth2AuthorizeRequest.Builder builder = OAuth2AuthorizeRequest.withClientRegistrationId(clientRegistrationId).principal(authentication);
+		builder.attributes(attributes -> {
+			if (servletRequest != null) {
+				attributes.put(HttpServletRequest.class.getName(), servletRequest);
+			}
+			if (servletResponse != null) {
+				attributes.put(HttpServletResponse.class.getName(), servletResponse);
+			}
+		});
+		OAuth2AuthorizeRequest authorizeRequest = builder.build();
 
 
 		// NOTE: 'authorizedClientManager.authorize()' needs to be executed on a dedicated thread via subscribeOn(Schedulers.elastic())
 		// NOTE: 'authorizedClientManager.authorize()' needs to be executed on a dedicated thread via subscribeOn(Schedulers.elastic())
 		// since it performs a blocking I/O operation using RestTemplate internally
 		// since it performs a blocking I/O operation using RestTemplate internally
@@ -470,8 +479,17 @@ public final class ServletOAuth2AuthorizedClientExchangeFilterFunction
 		}
 		}
 		HttpServletRequest servletRequest = getRequest(attrs);
 		HttpServletRequest servletRequest = getRequest(attrs);
 		HttpServletResponse servletResponse = getResponse(attrs);
 		HttpServletResponse servletResponse = getResponse(attrs);
-		OAuth2AuthorizeRequest reauthorizeRequest = new OAuth2AuthorizeRequest(
-				authorizedClient, authentication, servletRequest, servletResponse);
+
+		OAuth2AuthorizeRequest.Builder builder = OAuth2AuthorizeRequest.withAuthorizedClient(authorizedClient).principal(authentication);
+		builder.attributes(attributes -> {
+			if (servletRequest != null) {
+				attributes.put(HttpServletRequest.class.getName(), servletRequest);
+			}
+			if (servletResponse != null) {
+				attributes.put(HttpServletResponse.class.getName(), servletResponse);
+			}
+		});
+		OAuth2AuthorizeRequest reauthorizeRequest = builder.build();
 
 
 		// NOTE: 'authorizedClientManager.authorize()' needs to be executed on a dedicated thread via subscribeOn(Schedulers.elastic())
 		// NOTE: 'authorizedClientManager.authorize()' needs to be executed on a dedicated thread via subscribeOn(Schedulers.elastic())
 		// since it performs a blocking I/O operation using RestTemplate internally
 		// since it performs a blocking I/O operation using RestTemplate internally

+ 16 - 10
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/result/method/annotation/OAuth2AuthorizedClientArgumentResolver.java

@@ -23,15 +23,15 @@ import org.springframework.security.core.Authentication;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.context.ReactiveSecurityContextHolder;
 import org.springframework.security.core.context.ReactiveSecurityContextHolder;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
+import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
 import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
-import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
-import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizeRequest;
-import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.util.Assert;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
@@ -64,15 +64,15 @@ import reactor.core.publisher.Mono;
 public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMethodArgumentResolver {
 public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMethodArgumentResolver {
 	private static final AnonymousAuthenticationToken ANONYMOUS_USER_TOKEN = new AnonymousAuthenticationToken(
 	private static final AnonymousAuthenticationToken ANONYMOUS_USER_TOKEN = new AnonymousAuthenticationToken(
 			"anonymous", "anonymousUser", AuthorityUtils.createAuthorityList("ROLE_USER"));
 			"anonymous", "anonymousUser", AuthorityUtils.createAuthorityList("ROLE_USER"));
-	private ServerOAuth2AuthorizedClientManager authorizedClientManager;
+	private ReactiveOAuth2AuthorizedClientManager authorizedClientManager;
 
 
 	/**
 	/**
 	 * Constructs an {@code OAuth2AuthorizedClientArgumentResolver} using the provided parameters.
 	 * Constructs an {@code OAuth2AuthorizedClientArgumentResolver} using the provided parameters.
 	 *
 	 *
 	 * @since 5.2
 	 * @since 5.2
-	 * @param authorizedClientManager the {@link ServerOAuth2AuthorizedClientManager} which manages the authorized client(s)
+	 * @param authorizedClientManager the {@link ReactiveOAuth2AuthorizedClientManager} which manages the authorized client(s)
 	 */
 	 */
-	public OAuth2AuthorizedClientArgumentResolver(ServerOAuth2AuthorizedClientManager authorizedClientManager) {
+	public OAuth2AuthorizedClientArgumentResolver(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
 		Assert.notNull(authorizedClientManager, "authorizedClientManager cannot be null");
 		Assert.notNull(authorizedClientManager, "authorizedClientManager cannot be null");
 		this.authorizedClientManager = authorizedClientManager;
 		this.authorizedClientManager = authorizedClientManager;
 	}
 	}
@@ -90,7 +90,7 @@ public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMeth
 		this.authorizedClientManager = createDefaultAuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);
 		this.authorizedClientManager = createDefaultAuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);
 	}
 	}
 
 
-	private static ServerOAuth2AuthorizedClientManager createDefaultAuthorizedClientManager(
+	private static ReactiveOAuth2AuthorizedClientManager createDefaultAuthorizedClientManager(
 			ReactiveClientRegistrationRepository clientRegistrationRepository, ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
 			ReactiveClientRegistrationRepository clientRegistrationRepository, ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
 
 
 		ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
 		ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
@@ -100,7 +100,7 @@ public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMeth
 						.clientCredentials()
 						.clientCredentials()
 						.password()
 						.password()
 						.build();
 						.build();
-		DefaultServerOAuth2AuthorizedClientManager authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
+		DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
 				clientRegistrationRepository, authorizedClientRepository);
 				clientRegistrationRepository, authorizedClientRepository);
 		authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 		authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 
 
@@ -126,7 +126,7 @@ public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMeth
 		});
 		});
 	}
 	}
 
 
-	private Mono<ServerOAuth2AuthorizeRequest> authorizeRequest(String registrationId, ServerWebExchange exchange) {
+	private Mono<OAuth2AuthorizeRequest> authorizeRequest(String registrationId, ServerWebExchange exchange) {
 		Mono<Authentication> defaultedAuthentication = currentAuthentication();
 		Mono<Authentication> defaultedAuthentication = currentAuthentication();
 
 
 		Mono<String> defaultedRegistrationId = Mono.justOrEmpty(registrationId)
 		Mono<String> defaultedRegistrationId = Mono.justOrEmpty(registrationId)
@@ -137,7 +137,13 @@ public final class OAuth2AuthorizedClientArgumentResolver implements HandlerMeth
 				.switchIfEmpty(currentServerWebExchange());
 				.switchIfEmpty(currentServerWebExchange());
 
 
 		return Mono.zip(defaultedRegistrationId, defaultedAuthentication, defaultedExchange)
 		return Mono.zip(defaultedRegistrationId, defaultedAuthentication, defaultedExchange)
-				.map(t3 -> new ServerOAuth2AuthorizeRequest(t3.getT1(), t3.getT2(), t3.getT3()));
+				.map(t3 -> {
+					OAuth2AuthorizeRequest.Builder builder = OAuth2AuthorizeRequest.withClientRegistrationId(t3.getT1()).principal(t3.getT2());
+					if (t3.getT3() != null) {
+						builder.attribute(ServerWebExchange.class.getName(), t3.getT3());
+					}
+					return builder.build();
+				});
 	}
 	}
 
 
 	private Mono<Authentication> currentAuthentication() {
 	private Mono<Authentication> currentAuthentication() {

+ 0 - 112
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/ServerOAuth2AuthorizeRequest.java

@@ -1,112 +0,0 @@
-/*
- * Copyright 2002-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.security.oauth2.client.web.server;
-
-import org.springframework.lang.Nullable;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.util.Assert;
-import org.springframework.web.server.ServerWebExchange;
-
-/**
- * Represents a request the {@link ServerOAuth2AuthorizedClientManager} uses to
- * {@link ServerOAuth2AuthorizedClientManager#authorize(ServerOAuth2AuthorizeRequest) authorize} (or re-authorize)
- * the {@link ClientRegistration client} identified by the provided {@link #getClientRegistrationId() clientRegistrationId}.
- *
- * @author Joe Grandja
- * @since 5.2
- * @see ServerOAuth2AuthorizedClientManager
- */
-public class ServerOAuth2AuthorizeRequest {
-	private final String clientRegistrationId;
-	private final OAuth2AuthorizedClient authorizedClient;
-	private final Authentication principal;
-	private final ServerWebExchange serverWebExchange;
-
-	/**
-	 * Constructs a {@code ServerOAuth2AuthorizeRequest} using the provided parameters.
-	 *
-	 * @param clientRegistrationId the identifier for the {@link ClientRegistration client registration}
-	 * @param principal the {@code Principal} (to be) associated to the authorized client
-	 * @param serverWebExchange the {@code ServerWebExchange}
-	 */
-	public ServerOAuth2AuthorizeRequest(String clientRegistrationId, Authentication principal,
-										ServerWebExchange serverWebExchange) {
-		Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
-		Assert.notNull(principal, "principal cannot be null");
-		Assert.notNull(serverWebExchange, "serverWebExchange cannot be null");
-		this.clientRegistrationId = clientRegistrationId;
-		this.authorizedClient = null;
-		this.principal = principal;
-		this.serverWebExchange = serverWebExchange;
-	}
-
-	/**
-	 * Constructs a {@code ServerOAuth2AuthorizeRequest} using the provided parameters.
-	 *
-	 * @param authorizedClient the {@link OAuth2AuthorizedClient authorized client}
-	 * @param principal the {@code Principal} (to be) associated to the authorized client
-	 * @param serverWebExchange the {@code ServerWebExchange}
-	 */
-	public ServerOAuth2AuthorizeRequest(OAuth2AuthorizedClient authorizedClient, Authentication principal,
-										ServerWebExchange serverWebExchange) {
-		Assert.notNull(authorizedClient, "authorizedClient cannot be null");
-		Assert.notNull(principal, "principal cannot be null");
-		Assert.notNull(serverWebExchange, "serverWebExchange cannot be null");
-		this.clientRegistrationId = authorizedClient.getClientRegistration().getRegistrationId();
-		this.authorizedClient = authorizedClient;
-		this.principal = principal;
-		this.serverWebExchange = serverWebExchange;
-	}
-
-	/**
-	 * Returns the identifier for the {@link ClientRegistration client registration}.
-	 *
-	 * @return the identifier for the client registration
-	 */
-	public String getClientRegistrationId() {
-		return this.clientRegistrationId;
-	}
-
-	/**
-	 * Returns the {@link OAuth2AuthorizedClient authorized client} or {@code null} if it was not provided.
-	 *
-	 * @return the {@link OAuth2AuthorizedClient} or {@code null} if it was not provided
-	 */
-	@Nullable
-	public OAuth2AuthorizedClient getAuthorizedClient() {
-		return this.authorizedClient;
-	}
-
-	/**
-	 * Returns the {@code Principal} (to be) associated to the authorized client.
-	 *
-	 * @return the {@code Principal} (to be) associated to the authorized client
-	 */
-	public Authentication getPrincipal() {
-		return this.principal;
-	}
-
-	/**
-	 * Returns the {@link ServerWebExchange}.
-	 *
-	 * @return the {@link ServerWebExchange}
-	 */
-	public ServerWebExchange getServerWebExchange() {
-		return this.serverWebExchange;
-	}
-}

+ 29 - 30
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/ServerOAuth2AuthorizeRequestTests.java → oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/OAuth2AuthorizeRequestTests.java

@@ -13,81 +13,80 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package org.springframework.security.oauth2.client.web.server;
+package org.springframework.security.oauth2.client;
 
 
 import org.junit.Test;
 import org.junit.Test;
-import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
-import org.springframework.mock.web.server.MockServerWebExchange;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
 import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
 import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
 import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
 import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
 import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
 
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.*;
 
 
 /**
 /**
- * Tests for {@link ServerOAuth2AuthorizeRequest}.
+ * Tests for {@link OAuth2AuthorizeRequest}.
  *
  *
  * @author Joe Grandja
  * @author Joe Grandja
  */
  */
-public class ServerOAuth2AuthorizeRequestTests {
+public class OAuth2AuthorizeRequestTests {
 	private ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
 	private ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
 	private Authentication principal = new TestingAuthenticationToken("principal", "password");
 	private Authentication principal = new TestingAuthenticationToken("principal", "password");
 	private OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
 	private OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
 			this.clientRegistration, this.principal.getName(),
 			this.clientRegistration, this.principal.getName(),
 			TestOAuth2AccessTokens.scopes("read", "write"), TestOAuth2RefreshTokens.refreshToken());
 			TestOAuth2AccessTokens.scopes("read", "write"), TestOAuth2RefreshTokens.refreshToken());
-	private MockServerWebExchange serverWebExchange = MockServerWebExchange.builder(MockServerHttpRequest.get("/")).build();
 
 
 	@Test
 	@Test
-	public void constructorWhenClientRegistrationIdIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> new ServerOAuth2AuthorizeRequest((String) null, this.principal, this.serverWebExchange))
+	public void withClientRegistrationIdWhenClientRegistrationIdIsNullThenThrowIllegalArgumentException() {
+		assertThatThrownBy(() -> OAuth2AuthorizeRequest.withClientRegistrationId(null))
 				.isInstanceOf(IllegalArgumentException.class)
 				.isInstanceOf(IllegalArgumentException.class)
 				.hasMessage("clientRegistrationId cannot be empty");
 				.hasMessage("clientRegistrationId cannot be empty");
 	}
 	}
 
 
 	@Test
 	@Test
-	public void constructorWhenAuthorizedClientIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> new ServerOAuth2AuthorizeRequest((OAuth2AuthorizedClient) null, this.principal, this.serverWebExchange))
+	public void withAuthorizedClientWhenAuthorizedClientIsNullThenThrowIllegalArgumentException() {
+		assertThatThrownBy(() -> OAuth2AuthorizeRequest.withAuthorizedClient(null))
 				.isInstanceOf(IllegalArgumentException.class)
 				.isInstanceOf(IllegalArgumentException.class)
 				.hasMessage("authorizedClient cannot be null");
 				.hasMessage("authorizedClient cannot be null");
 	}
 	}
 
 
 	@Test
 	@Test
-	public void constructorWhenPrincipalIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> new ServerOAuth2AuthorizeRequest(this.clientRegistration.getRegistrationId(), null, this.serverWebExchange))
+	public void withClientRegistrationIdWhenPrincipalIsNullThenThrowIllegalArgumentException() {
+		assertThatThrownBy(() -> OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId()).build())
 				.isInstanceOf(IllegalArgumentException.class)
 				.isInstanceOf(IllegalArgumentException.class)
 				.hasMessage("principal cannot be null");
 				.hasMessage("principal cannot be null");
 	}
 	}
 
 
 	@Test
 	@Test
-	public void constructorWhenServerWebExchangeIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> new ServerOAuth2AuthorizeRequest(this.clientRegistration.getRegistrationId(), this.principal, null))
-				.isInstanceOf(IllegalArgumentException.class)
-				.hasMessage("serverWebExchange cannot be null");
-	}
-
-	@Test
-	public void constructorClientRegistrationIdWhenAllValuesProvidedThenAllValuesAreSet() {
-		ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
-				this.clientRegistration.getRegistrationId(), this.principal, this.serverWebExchange);
+	public void withClientRegistrationIdWhenAllValuesProvidedThenAllValuesAreSet() {
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.attributes(attrs -> {
+					attrs.put("name1", "value1");
+					attrs.put("name2", "value2");
+				})
+				.build();
 
 
 		assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.clientRegistration.getRegistrationId());
 		assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.clientRegistration.getRegistrationId());
+		assertThat(authorizeRequest.getAuthorizedClient()).isNull();
 		assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
 		assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
-		assertThat(authorizeRequest.getServerWebExchange()).isEqualTo(this.serverWebExchange);
+		assertThat(authorizeRequest.getAttributes()).contains(entry("name1", "value1"), entry("name2", "value2"));
 	}
 	}
 
 
 	@Test
 	@Test
-	public void constructorAuthorizedClientWhenAllValuesProvidedThenAllValuesAreSet() {
-		ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
-				this.authorizedClient, this.principal, this.serverWebExchange);
+	public void withAuthorizedClientWhenAllValuesProvidedThenAllValuesAreSet() {
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
+				.principal(this.principal)
+				.attributes(attrs -> {
+					attrs.put("name1", "value1");
+					attrs.put("name2", "value2");
+				})
+				.build();
 
 
 		assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.authorizedClient.getClientRegistration().getRegistrationId());
 		assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.authorizedClient.getClientRegistration().getRegistrationId());
 		assertThat(authorizeRequest.getAuthorizedClient()).isEqualTo(this.authorizedClient);
 		assertThat(authorizeRequest.getAuthorizedClient()).isEqualTo(this.authorizedClient);
 		assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
 		assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
-		assertThat(authorizeRequest.getServerWebExchange()).isEqualTo(this.serverWebExchange);
+		assertThat(authorizeRequest.getAttributes()).contains(entry("name1", "value1"), entry("name2", "value2"));
 	}
 	}
 }
 }

+ 83 - 18
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManagerTests.java

@@ -23,6 +23,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
 import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
+import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
@@ -33,6 +34,8 @@ import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
 
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.function.Function;
@@ -114,10 +117,36 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
 				.hasMessage("authorizeRequest cannot be null");
 				.hasMessage("authorizeRequest cannot be null");
 	}
 	}
 
 
+	@Test
+	public void authorizeWhenHttpServletRequestIsNullThenThrowIllegalArgumentException() {
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.build();
+		assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest))
+				.isInstanceOf(IllegalArgumentException.class)
+				.hasMessage("servletRequest cannot be null");
+	}
+
+	@Test
+	public void authorizeWhenHttpServletResponseIsNullThenThrowIllegalArgumentException() {
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.attribute(HttpServletRequest.class.getName(), this.request)
+				.build();
+		assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest))
+				.isInstanceOf(IllegalArgumentException.class)
+				.hasMessage("servletResponse cannot be null");
+	}
+
 	@Test
 	@Test
 	public void authorizeWhenClientRegistrationNotFoundThenThrowIllegalArgumentException() {
 	public void authorizeWhenClientRegistrationNotFoundThenThrowIllegalArgumentException() {
-		OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
-				"invalid-registration-id", this.principal, this.request, this.response);
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("invalid-registration-id")
+				.principal(this.principal)
+				.attributes(attrs -> {
+					attrs.put(HttpServletRequest.class.getName(), this.request);
+					attrs.put(HttpServletResponse.class.getName(), this.response);
+				})
+				.build();
 		assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest))
 		assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest))
 				.isInstanceOf(IllegalArgumentException.class)
 				.isInstanceOf(IllegalArgumentException.class)
 				.hasMessage("Could not find ClientRegistration with id 'invalid-registration-id'");
 				.hasMessage("Could not find ClientRegistration with id 'invalid-registration-id'");
@@ -129,8 +158,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
 		when(this.clientRegistrationRepository.findByRegistrationId(
 		when(this.clientRegistrationRepository.findByRegistrationId(
 				eq(this.clientRegistration.getRegistrationId()))).thenReturn(this.clientRegistration);
 				eq(this.clientRegistration.getRegistrationId()))).thenReturn(this.clientRegistration);
 
 
-		OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
-				this.clientRegistration.getRegistrationId(), this.principal, this.request, this.response);
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.attributes(attrs -> {
+					attrs.put(HttpServletRequest.class.getName(), this.request);
+					attrs.put(HttpServletResponse.class.getName(), this.response);
+				})
+				.build();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -154,8 +188,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
 
 
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(this.authorizedClient);
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(this.authorizedClient);
 
 
-		OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
-				this.clientRegistration.getRegistrationId(), this.principal, this.request, this.response);
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.attributes(attrs -> {
+					attrs.put(HttpServletRequest.class.getName(), this.request);
+					attrs.put(HttpServletResponse.class.getName(), this.response);
+				})
+				.build();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -185,8 +224,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
 
 
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(reauthorizedClient);
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(reauthorizedClient);
 
 
-		OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
-				this.clientRegistration.getRegistrationId(), this.principal, this.request, this.response);
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.attributes(attrs -> {
+					attrs.put(HttpServletRequest.class.getName(), this.request);
+					attrs.put(HttpServletResponse.class.getName(), this.response);
+				})
+				.build();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -212,8 +256,9 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
 		// Set custom contextAttributesMapper
 		// Set custom contextAttributesMapper
 		this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
 		this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
 			Map<String, Object> contextAttributes = new HashMap<>();
 			Map<String, Object> contextAttributes = new HashMap<>();
-			String username = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.USERNAME);
-			String password = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.PASSWORD);
+			HttpServletRequest servletRequest = authorizeRequest.getAttribute(HttpServletRequest.class.getName());
+			String username = servletRequest.getParameter(OAuth2ParameterNames.USERNAME);
+			String password = servletRequest.getParameter(OAuth2ParameterNames.PASSWORD);
 			if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
 			if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
 				contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
 				contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
 				contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
 				contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
@@ -224,8 +269,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
 		this.request.addParameter(OAuth2ParameterNames.USERNAME, "username");
 		this.request.addParameter(OAuth2ParameterNames.USERNAME, "username");
 		this.request.addParameter(OAuth2ParameterNames.PASSWORD, "password");
 		this.request.addParameter(OAuth2ParameterNames.PASSWORD, "password");
 
 
-		OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
-				this.clientRegistration.getRegistrationId(), this.principal, this.request, this.response);
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.attributes(attrs -> {
+					attrs.put(HttpServletRequest.class.getName(), this.request);
+					attrs.put(HttpServletResponse.class.getName(), this.response);
+				})
+				.build();
 		this.authorizedClientManager.authorize(authorizeRequest);
 		this.authorizedClientManager.authorize(authorizeRequest);
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -240,8 +290,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
 	@SuppressWarnings("unchecked")
 	@SuppressWarnings("unchecked")
 	@Test
 	@Test
 	public void reauthorizeWhenUnsupportedProviderThenNotReauthorized() {
 	public void reauthorizeWhenUnsupportedProviderThenNotReauthorized() {
-		OAuth2AuthorizeRequest reauthorizeRequest = new OAuth2AuthorizeRequest(
-				this.authorizedClient, this.principal, this.request, this.response);
+		OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
+				.principal(this.principal)
+				.attributes(attrs -> {
+					attrs.put(HttpServletRequest.class.getName(), this.request);
+					attrs.put(HttpServletResponse.class.getName(), this.response);
+				})
+				.build();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest);
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest);
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -266,8 +321,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
 
 
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(reauthorizedClient);
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(reauthorizedClient);
 
 
-		OAuth2AuthorizeRequest reauthorizeRequest = new OAuth2AuthorizeRequest(
-				this.authorizedClient, this.principal, this.request, this.response);
+		OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
+				.principal(this.principal)
+				.attributes(attrs -> {
+					attrs.put(HttpServletRequest.class.getName(), this.request);
+					attrs.put(HttpServletResponse.class.getName(), this.response);
+				})
+				.build();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest);
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest);
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -297,8 +357,13 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
 
 
 		this.request.addParameter(OAuth2ParameterNames.SCOPE, "read write");
 		this.request.addParameter(OAuth2ParameterNames.SCOPE, "read write");
 
 
-		OAuth2AuthorizeRequest reauthorizeRequest = new OAuth2AuthorizeRequest(
-				this.authorizedClient, this.principal, this.request, this.response);
+		OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
+				.principal(this.principal)
+				.attributes(attrs -> {
+					attrs.put(HttpServletRequest.class.getName(), this.request);
+					attrs.put(HttpServletResponse.class.getName(), this.response);
+				})
+				.build();
 		this.authorizedClientManager.authorize(reauthorizeRequest);
 		this.authorizedClientManager.authorize(reauthorizeRequest);
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());

+ 57 - 28
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/DefaultServerOAuth2AuthorizedClientManagerTests.java → oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManagerTests.java

@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * limitations under the License.
  */
  */
-package org.springframework.security.oauth2.client.web.server;
+package org.springframework.security.oauth2.client.web;
 
 
 import org.junit.Before;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.Test;
@@ -24,11 +24,13 @@ import org.springframework.mock.web.server.MockServerWebExchange;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
 import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
+import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
 import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
+import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
 import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
 import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
 import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
@@ -48,16 +50,16 @@ import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.*;
 import static org.mockito.Mockito.*;
 
 
 /**
 /**
- * Tests for {@link DefaultServerOAuth2AuthorizedClientManager}.
+ * Tests for {@link DefaultReactiveOAuth2AuthorizedClientManager}.
  *
  *
  * @author Joe Grandja
  * @author Joe Grandja
  */
  */
-public class DefaultServerOAuth2AuthorizedClientManagerTests {
+public class DefaultReactiveOAuth2AuthorizedClientManagerTests {
 	private ReactiveClientRegistrationRepository clientRegistrationRepository;
 	private ReactiveClientRegistrationRepository clientRegistrationRepository;
 	private ServerOAuth2AuthorizedClientRepository authorizedClientRepository;
 	private ServerOAuth2AuthorizedClientRepository authorizedClientRepository;
 	private ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider;
 	private ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider;
 	private Function contextAttributesMapper;
 	private Function contextAttributesMapper;
-	private DefaultServerOAuth2AuthorizedClientManager authorizedClientManager;
+	private DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager;
 	private ClientRegistration clientRegistration;
 	private ClientRegistration clientRegistration;
 	private Authentication principal;
 	private Authentication principal;
 	private OAuth2AuthorizedClient authorizedClient;
 	private OAuth2AuthorizedClient authorizedClient;
@@ -77,7 +79,7 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.empty());
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.empty());
 		this.contextAttributesMapper = mock(Function.class);
 		this.contextAttributesMapper = mock(Function.class);
 		when(this.contextAttributesMapper.apply(any())).thenReturn(Mono.just(Collections.emptyMap()));
 		when(this.contextAttributesMapper.apply(any())).thenReturn(Mono.just(Collections.emptyMap()));
-		this.authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
+		this.authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
 				this.clientRegistrationRepository, this.authorizedClientRepository);
 				this.clientRegistrationRepository, this.authorizedClientRepository);
 		this.authorizedClientManager.setAuthorizedClientProvider(this.authorizedClientProvider);
 		this.authorizedClientManager.setAuthorizedClientProvider(this.authorizedClientProvider);
 		this.authorizedClientManager.setContextAttributesMapper(this.contextAttributesMapper);
 		this.authorizedClientManager.setContextAttributesMapper(this.contextAttributesMapper);
@@ -91,14 +93,14 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 
 
 	@Test
 	@Test
 	public void constructorWhenClientRegistrationRepositoryIsNullThenThrowIllegalArgumentException() {
 	public void constructorWhenClientRegistrationRepositoryIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> new DefaultServerOAuth2AuthorizedClientManager(null, this.authorizedClientRepository))
+		assertThatThrownBy(() -> new DefaultReactiveOAuth2AuthorizedClientManager(null, this.authorizedClientRepository))
 				.isInstanceOf(IllegalArgumentException.class)
 				.isInstanceOf(IllegalArgumentException.class)
 				.hasMessage("clientRegistrationRepository cannot be null");
 				.hasMessage("clientRegistrationRepository cannot be null");
 	}
 	}
 
 
 	@Test
 	@Test
 	public void constructorWhenOAuth2AuthorizedClientRepositoryIsNullThenThrowIllegalArgumentException() {
 	public void constructorWhenOAuth2AuthorizedClientRepositoryIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> new DefaultServerOAuth2AuthorizedClientManager(this.clientRegistrationRepository, null))
+		assertThatThrownBy(() -> new DefaultReactiveOAuth2AuthorizedClientManager(this.clientRegistrationRepository, null))
 				.isInstanceOf(IllegalArgumentException.class)
 				.isInstanceOf(IllegalArgumentException.class)
 				.hasMessage("authorizedClientRepository cannot be null");
 				.hasMessage("authorizedClientRepository cannot be null");
 	}
 	}
@@ -117,6 +119,16 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 				.hasMessage("contextAttributesMapper cannot be null");
 				.hasMessage("contextAttributesMapper cannot be null");
 	}
 	}
 
 
+	@Test
+	public void authorizeWhenServerWebExchangeIsNullThenThrowIllegalArgumentException() {
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.build();
+		assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest).block())
+				.isInstanceOf(IllegalArgumentException.class)
+				.hasMessage("serverWebExchange cannot be null");
+	}
+
 	@Test
 	@Test
 	public void authorizeWhenRequestIsNullThenThrowIllegalArgumentException() {
 	public void authorizeWhenRequestIsNullThenThrowIllegalArgumentException() {
 		assertThatThrownBy(() -> this.authorizedClientManager.authorize(null).block())
 		assertThatThrownBy(() -> this.authorizedClientManager.authorize(null).block())
@@ -126,8 +138,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 
 
 	@Test
 	@Test
 	public void authorizeWhenClientRegistrationNotFoundThenThrowIllegalArgumentException() {
 	public void authorizeWhenClientRegistrationNotFoundThenThrowIllegalArgumentException() {
-		ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
-				"invalid-registration-id", this.principal, this.serverWebExchange);
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("invalid-registration-id")
+				.principal(this.principal)
+				.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
+				.build();
 		assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest).block())
 		assertThatThrownBy(() -> this.authorizedClientManager.authorize(authorizeRequest).block())
 				.isInstanceOf(IllegalArgumentException.class)
 				.isInstanceOf(IllegalArgumentException.class)
 				.hasMessage("Could not find ClientRegistration with id 'invalid-registration-id'");
 				.hasMessage("Could not find ClientRegistration with id 'invalid-registration-id'");
@@ -139,8 +153,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 		when(this.clientRegistrationRepository.findByRegistrationId(
 		when(this.clientRegistrationRepository.findByRegistrationId(
 				eq(this.clientRegistration.getRegistrationId()))).thenReturn(Mono.just(this.clientRegistration));
 				eq(this.clientRegistration.getRegistrationId()))).thenReturn(Mono.just(this.clientRegistration));
 
 
-		ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
-				this.clientRegistration.getRegistrationId(), this.principal, this.serverWebExchange);
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
+				.build();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -165,8 +181,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 		when(this.authorizedClientProvider.authorize(
 		when(this.authorizedClientProvider.authorize(
 				any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(this.authorizedClient));
 				any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(this.authorizedClient));
 
 
-		ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
-				this.clientRegistration.getRegistrationId(), this.principal, this.serverWebExchange);
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
+				.build();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -196,8 +214,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 
 
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(reauthorizedClient));
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(reauthorizedClient));
 
 
-		ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
-				this.clientRegistration.getRegistrationId(), this.principal, this.serverWebExchange);
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
+				.build();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -221,8 +241,9 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(this.authorizedClient));
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(this.authorizedClient));
 
 
 		// Set custom contextAttributesMapper capable of mapping the form parameters
 		// Set custom contextAttributesMapper capable of mapping the form parameters
-		this.authorizedClientManager.setContextAttributesMapper(authorizeRequest ->
-			Mono.just(authorizeRequest.getServerWebExchange())
+		this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
+			ServerWebExchange serverWebExchange = authorizeRequest.getAttribute(ServerWebExchange.class.getName());
+			return Mono.just(serverWebExchange)
 					.flatMap(ServerWebExchange::getFormData)
 					.flatMap(ServerWebExchange::getFormData)
 					.map(formData -> {
 					.map(formData -> {
 						Map<String, Object> contextAttributes = new HashMap<>();
 						Map<String, Object> contextAttributes = new HashMap<>();
@@ -233,8 +254,8 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 							contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
 							contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
 						}
 						}
 						return contextAttributes;
 						return contextAttributes;
-					})
-		);
+					});
+		});
 
 
 		this.serverWebExchange = MockServerWebExchange.builder(
 		this.serverWebExchange = MockServerWebExchange.builder(
 				MockServerHttpRequest
 				MockServerHttpRequest
@@ -243,8 +264,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 						.body("username=username&password=password"))
 						.body("username=username&password=password"))
 				.build();
 				.build();
 
 
-		ServerOAuth2AuthorizeRequest authorizeRequest = new ServerOAuth2AuthorizeRequest(
-				this.clientRegistration.getRegistrationId(), this.principal, this.serverWebExchange);
+		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId(this.clientRegistration.getRegistrationId())
+				.principal(this.principal)
+				.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
+				.build();
 		this.authorizedClientManager.authorize(authorizeRequest).block();
 		this.authorizedClientManager.authorize(authorizeRequest).block();
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -259,8 +282,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 	@SuppressWarnings("unchecked")
 	@SuppressWarnings("unchecked")
 	@Test
 	@Test
 	public void reauthorizeWhenUnsupportedProviderThenNotReauthorized() {
 	public void reauthorizeWhenUnsupportedProviderThenNotReauthorized() {
-		ServerOAuth2AuthorizeRequest reauthorizeRequest = new ServerOAuth2AuthorizeRequest(
-				this.authorizedClient, this.principal, this.serverWebExchange);
+		OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
+				.principal(this.principal)
+				.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
+				.build();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest).block();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest).block();
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -285,8 +310,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 
 
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(reauthorizedClient));
 		when(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class))).thenReturn(Mono.just(reauthorizedClient));
 
 
-		ServerOAuth2AuthorizeRequest reauthorizeRequest = new ServerOAuth2AuthorizeRequest(
-				this.authorizedClient, this.principal, this.serverWebExchange);
+		OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
+				.principal(this.principal)
+				.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
+				.build();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest).block();
 		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(reauthorizeRequest).block();
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
@@ -312,7 +339,7 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 
 
 		// Override the mock with the default
 		// Override the mock with the default
 		this.authorizedClientManager.setContextAttributesMapper(
 		this.authorizedClientManager.setContextAttributesMapper(
-				new DefaultServerOAuth2AuthorizedClientManager.DefaultContextAttributesMapper());
+				new DefaultReactiveOAuth2AuthorizedClientManager.DefaultContextAttributesMapper());
 
 
 		this.serverWebExchange = MockServerWebExchange.builder(
 		this.serverWebExchange = MockServerWebExchange.builder(
 				MockServerHttpRequest
 				MockServerHttpRequest
@@ -320,8 +347,10 @@ public class DefaultServerOAuth2AuthorizedClientManagerTests {
 						.queryParam(OAuth2ParameterNames.SCOPE, "read write"))
 						.queryParam(OAuth2ParameterNames.SCOPE, "read write"))
 				.build();
 				.build();
 
 
-		ServerOAuth2AuthorizeRequest reauthorizeRequest = new ServerOAuth2AuthorizeRequest(
-				this.authorizedClient, this.principal, this.serverWebExchange);
+		OAuth2AuthorizeRequest reauthorizeRequest = OAuth2AuthorizeRequest.withAuthorizedClient(this.authorizedClient)
+				.principal(this.principal)
+				.attribute(ServerWebExchange.class.getName(), this.serverWebExchange)
+				.build();
 		this.authorizedClientManager.authorize(reauthorizeRequest).block();
 		this.authorizedClientManager.authorize(reauthorizeRequest).block();
 
 
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
 		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());

+ 0 - 104
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/OAuth2AuthorizeRequestTests.java

@@ -1,104 +0,0 @@
-/*
- * Copyright 2002-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.security.oauth2.client.web;
-
-import org.junit.Test;
-import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.mock.web.MockHttpServletResponse;
-import org.springframework.security.authentication.TestingAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
-import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
-import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-
-/**
- * Tests for {@link OAuth2AuthorizeRequest}.
- *
- * @author Joe Grandja
- */
-public class OAuth2AuthorizeRequestTests {
-	private ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
-	private Authentication principal = new TestingAuthenticationToken("principal", "password");
-	private OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
-			this.clientRegistration, this.principal.getName(),
-			TestOAuth2AccessTokens.scopes("read", "write"), TestOAuth2RefreshTokens.refreshToken());
-	private MockHttpServletRequest servletRequest = new MockHttpServletRequest();
-	private MockHttpServletResponse servletResponse = new MockHttpServletResponse();
-
-	@Test
-	public void constructorWhenClientRegistrationIdIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> new OAuth2AuthorizeRequest((String) null, this.principal, this.servletRequest, this.servletResponse))
-				.isInstanceOf(IllegalArgumentException.class)
-				.hasMessage("clientRegistrationId cannot be empty");
-	}
-
-	@Test
-	public void constructorWhenAuthorizedClientIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> new OAuth2AuthorizeRequest((OAuth2AuthorizedClient) null, this.principal, this.servletRequest, this.servletResponse))
-				.isInstanceOf(IllegalArgumentException.class)
-				.hasMessage("authorizedClient cannot be null");
-	}
-
-	@Test
-	public void constructorWhenPrincipalIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> new OAuth2AuthorizeRequest(this.clientRegistration.getRegistrationId(), null, this.servletRequest, this.servletResponse))
-				.isInstanceOf(IllegalArgumentException.class)
-				.hasMessage("principal cannot be null");
-	}
-
-	@Test
-	public void constructorWhenServletRequestIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> new OAuth2AuthorizeRequest(this.clientRegistration.getRegistrationId(), this.principal, null, this.servletResponse))
-				.isInstanceOf(IllegalArgumentException.class)
-				.hasMessage("servletRequest cannot be null");
-	}
-
-	@Test
-	public void constructorWhenServletResponseIsNullThenThrowIllegalArgumentException() {
-		assertThatThrownBy(() -> new OAuth2AuthorizeRequest(this.clientRegistration.getRegistrationId(), this.principal, this.servletRequest, null))
-				.isInstanceOf(IllegalArgumentException.class)
-				.hasMessage("servletResponse cannot be null");
-	}
-
-	@Test
-	public void constructorClientRegistrationIdWhenAllValuesProvidedThenAllValuesAreSet() {
-		OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
-				this.clientRegistration.getRegistrationId(), this.principal, this.servletRequest, this.servletResponse);
-
-		assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.clientRegistration.getRegistrationId());
-		assertThat(authorizeRequest.getAuthorizedClient()).isNull();
-		assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
-		assertThat(authorizeRequest.getServletRequest()).isEqualTo(this.servletRequest);
-		assertThat(authorizeRequest.getServletResponse()).isEqualTo(this.servletResponse);
-	}
-
-	@Test
-	public void constructorAuthorizedClientWhenAllValuesProvidedThenAllValuesAreSet() {
-		OAuth2AuthorizeRequest authorizeRequest = new OAuth2AuthorizeRequest(
-				this.authorizedClient, this.principal, this.servletRequest, this.servletResponse);
-
-		assertThat(authorizeRequest.getClientRegistrationId()).isEqualTo(this.authorizedClient.getClientRegistration().getRegistrationId());
-		assertThat(authorizeRequest.getAuthorizedClient()).isEqualTo(this.authorizedClient);
-		assertThat(authorizeRequest.getPrincipal()).isEqualTo(this.principal);
-		assertThat(authorizeRequest.getServletRequest()).isEqualTo(this.servletRequest);
-		assertThat(authorizeRequest.getServletResponse()).isEqualTo(this.servletResponse);
-	}
-}

+ 3 - 2
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/method/annotation/OAuth2AuthorizedClientArgumentResolverTests.java

@@ -293,8 +293,9 @@ public class OAuth2AuthorizedClientArgumentResolverTests {
 		// Set custom contextAttributesMapper
 		// Set custom contextAttributesMapper
 		authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
 		authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
 			Map<String, Object> contextAttributes = new HashMap<>();
 			Map<String, Object> contextAttributes = new HashMap<>();
-			String username = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.USERNAME);
-			String password = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.PASSWORD);
+			HttpServletRequest servletRequest = authorizeRequest.getAttribute(HttpServletRequest.class.getName());
+			String username = servletRequest.getParameter(OAuth2ParameterNames.USERNAME);
+			String password = servletRequest.getParameter(OAuth2ParameterNames.PASSWORD);
 			if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
 			if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
 				contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
 				contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
 				contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
 				contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);

+ 20 - 19
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunctionTests.java

@@ -55,7 +55,7 @@ import org.springframework.security.oauth2.client.endpoint.WebClientReactiveClie
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
 import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
-import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.core.OAuth2AccessToken;
 import org.springframework.security.oauth2.core.OAuth2AccessToken;
 import org.springframework.security.oauth2.core.OAuth2RefreshToken;
 import org.springframework.security.oauth2.core.OAuth2RefreshToken;
@@ -127,7 +127,7 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
 			Instant.now(),
 			Instant.now(),
 			Instant.now().plus(Duration.ofDays(1)));
 			Instant.now().plus(Duration.ofDays(1)));
 
 
-	private DefaultServerOAuth2AuthorizedClientManager authorizedClientManager;
+	private DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager;
 
 
 	@Before
 	@Before
 	public void setup() {
 	public void setup() {
@@ -138,7 +138,7 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
 						.clientCredentials(configurer -> configurer.accessTokenResponseClient(this.clientCredentialsTokenResponseClient))
 						.clientCredentials(configurer -> configurer.accessTokenResponseClient(this.clientCredentialsTokenResponseClient))
 						.password(configurer -> configurer.accessTokenResponseClient(this.passwordTokenResponseClient))
 						.password(configurer -> configurer.accessTokenResponseClient(this.passwordTokenResponseClient))
 						.build();
 						.build();
-		this.authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
+		this.authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
 				this.clientRegistrationRepository, this.authorizedClientRepository);
 				this.clientRegistrationRepository, this.authorizedClientRepository);
 		this.authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 		this.authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 		this.function = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
 		this.function = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
@@ -161,7 +161,7 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
 	public void setClientCredentialsTokenResponseClientWhenNotDefaultAuthorizedClientManagerThenThrowIllegalStateException() {
 	public void setClientCredentialsTokenResponseClientWhenNotDefaultAuthorizedClientManagerThenThrowIllegalStateException() {
 		assertThatThrownBy(() -> this.function.setClientCredentialsTokenResponseClient(new WebClientReactiveClientCredentialsTokenResponseClient()))
 		assertThatThrownBy(() -> this.function.setClientCredentialsTokenResponseClient(new WebClientReactiveClientCredentialsTokenResponseClient()))
 				.isInstanceOf(IllegalStateException.class)
 				.isInstanceOf(IllegalStateException.class)
-				.hasMessage("The client cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager)\". " +
+				.hasMessage("The client cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)\". " +
 						"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
 						"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
 	}
 	}
 
 
@@ -169,7 +169,7 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
 	public void setAccessTokenExpiresSkewWhenNotDefaultAuthorizedClientManagerThenThrowIllegalStateException() {
 	public void setAccessTokenExpiresSkewWhenNotDefaultAuthorizedClientManagerThenThrowIllegalStateException() {
 		assertThatThrownBy(() -> this.function.setAccessTokenExpiresSkew(Duration.ofSeconds(30)))
 		assertThatThrownBy(() -> this.function.setAccessTokenExpiresSkew(Duration.ofSeconds(30)))
 				.isInstanceOf(IllegalStateException.class)
 				.isInstanceOf(IllegalStateException.class)
-				.hasMessage("The accessTokenExpiresSkew cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ServerOAuth2AuthorizedClientManager)\". " +
+				.hasMessage("The accessTokenExpiresSkew cannot be set when the constructor used is \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ReactiveOAuth2AuthorizedClientManager)\". " +
 						"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
 						"Instead, use the constructor \"ServerOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository)\".");
 	}
 	}
 
 
@@ -429,20 +429,21 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
 		when(this.authorizedClientRepository.loadAuthorizedClient(eq(registration.getRegistrationId()), eq(authentication), any())).thenReturn(Mono.empty());
 		when(this.authorizedClientRepository.loadAuthorizedClient(eq(registration.getRegistrationId()), eq(authentication), any())).thenReturn(Mono.empty());
 
 
 		// Set custom contextAttributesMapper capable of mapping the form parameters
 		// Set custom contextAttributesMapper capable of mapping the form parameters
-		this.authorizedClientManager.setContextAttributesMapper(authorizeRequest ->
-				Mono.just(authorizeRequest.getServerWebExchange())
-						.flatMap(ServerWebExchange::getFormData)
-						.map(formData -> {
-							Map<String, Object> contextAttributes = new HashMap<>();
-							String username = formData.getFirst(OAuth2ParameterNames.USERNAME);
-							String password = formData.getFirst(OAuth2ParameterNames.PASSWORD);
-							if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
-								contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-								contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
-							}
-							return contextAttributes;
-						})
-		);
+		this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
+			ServerWebExchange serverWebExchange = authorizeRequest.getAttribute(ServerWebExchange.class.getName());
+			return Mono.just(serverWebExchange)
+					.flatMap(ServerWebExchange::getFormData)
+					.map(formData -> {
+						Map<String, Object> contextAttributes = new HashMap<>();
+						String username = formData.getFirst(OAuth2ParameterNames.USERNAME);
+						String password = formData.getFirst(OAuth2ParameterNames.PASSWORD);
+						if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
+							contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
+							contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
+						}
+						return contextAttributes;
+					});
+		});
 
 
 		this.serverWebExchange = MockServerWebExchange.builder(
 		this.serverWebExchange = MockServerWebExchange.builder(
 				MockServerHttpRequest
 				MockServerHttpRequest

+ 4 - 2
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunctionTests.java

@@ -81,6 +81,7 @@ import reactor.core.publisher.BaseSubscriber;
 import reactor.core.publisher.Mono;
 import reactor.core.publisher.Mono;
 import reactor.util.context.Context;
 import reactor.util.context.Context;
 
 
+import javax.servlet.http.HttpServletRequest;
 import java.net.URI;
 import java.net.URI;
 import java.time.Duration;
 import java.time.Duration;
 import java.time.Instant;
 import java.time.Instant;
@@ -466,8 +467,9 @@ public class ServletOAuth2AuthorizedClientExchangeFilterFunctionTests {
 		// Set custom contextAttributesMapper
 		// Set custom contextAttributesMapper
 		this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
 		this.authorizedClientManager.setContextAttributesMapper(authorizeRequest -> {
 			Map<String, Object> contextAttributes = new HashMap<>();
 			Map<String, Object> contextAttributes = new HashMap<>();
-			String username = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.USERNAME);
-			String password = authorizeRequest.getServletRequest().getParameter(OAuth2ParameterNames.PASSWORD);
+			HttpServletRequest servletRequest = authorizeRequest.getAttribute(HttpServletRequest.class.getName());
+			String username = servletRequest.getParameter(OAuth2ParameterNames.USERNAME);
+			String password = servletRequest.getParameter(OAuth2ParameterNames.PASSWORD);
 			if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
 			if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
 				contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
 				contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
 				contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
 				contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);

+ 2 - 2
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/reactive/result/method/annotation/OAuth2AuthorizedClientArgumentResolverTests.java

@@ -36,7 +36,7 @@ import org.springframework.security.oauth2.client.authentication.OAuth2Authentic
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
 import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
-import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
 import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
 import org.springframework.util.ReflectionUtils;
 import org.springframework.util.ReflectionUtils;
@@ -79,7 +79,7 @@ public class OAuth2AuthorizedClientArgumentResolverTests {
 						.refreshToken()
 						.refreshToken()
 						.clientCredentials()
 						.clientCredentials()
 						.build();
 						.build();
-		DefaultServerOAuth2AuthorizedClientManager authorizedClientManager = new DefaultServerOAuth2AuthorizedClientManager(
+		DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
 				this.clientRegistrationRepository, this.authorizedClientRepository);
 				this.clientRegistrationRepository, this.authorizedClientRepository);
 		authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 		authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 		this.argumentResolver = new OAuth2AuthorizedClientArgumentResolver(authorizedClientManager);
 		this.argumentResolver = new OAuth2AuthorizedClientArgumentResolver(authorizedClientManager);

+ 6 - 6
samples/boot/oauth2webclient-webflux/src/main/java/sample/config/WebClientConfig.java

@@ -22,8 +22,8 @@ import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClient
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction;
 import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction;
-import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizedClientManager;
-import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
 import org.springframework.web.reactive.function.client.WebClient;
 import org.springframework.web.reactive.function.client.WebClient;
 
 
@@ -35,7 +35,7 @@ import org.springframework.web.reactive.function.client.WebClient;
 public class WebClientConfig {
 public class WebClientConfig {
 
 
 	@Bean
 	@Bean
-	WebClient webClient(ServerOAuth2AuthorizedClientManager authorizedClientManager) {
+	WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
 		ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
 		ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
 				new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
 				new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
 		oauth.setDefaultOAuth2AuthorizedClient(true);
 		oauth.setDefaultOAuth2AuthorizedClient(true);
@@ -45,7 +45,7 @@ public class WebClientConfig {
 	}
 	}
 
 
 	@Bean
 	@Bean
-	ServerOAuth2AuthorizedClientManager authorizedClientManager(
+	ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
 			ReactiveClientRegistrationRepository clientRegistrationRepository,
 			ReactiveClientRegistrationRepository clientRegistrationRepository,
 			ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
 			ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
 
 
@@ -56,8 +56,8 @@ public class WebClientConfig {
 						.clientCredentials()
 						.clientCredentials()
 						.password()
 						.password()
 						.build();
 						.build();
-		DefaultServerOAuth2AuthorizedClientManager authorizedClientManager =
-				new DefaultServerOAuth2AuthorizedClientManager(
+		DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager =
+				new DefaultReactiveOAuth2AuthorizedClientManager(
 						clientRegistrationRepository, authorizedClientRepository);
 						clientRegistrationRepository, authorizedClientRepository);
 		authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 		authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 
 

+ 1 - 1
samples/boot/oauth2webclient/src/main/java/sample/config/WebClientConfig.java

@@ -22,7 +22,7 @@ import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
-import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction;
 import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction;
 import org.springframework.web.reactive.function.client.WebClient;
 import org.springframework.web.reactive.function.client.WebClient;