Bladeren bron

Remove Resource Owner Password Credentials grant

Closes gh-17446
Joe Grandja 1 maand geleden
bovenliggende
commit
cfe38957d7
54 gewijzigde bestanden met toevoegingen van 103 en 3996 verwijderingen
  1. 0 22
      config/src/main/java/org/springframework/security/config/annotation/web/configuration/OAuth2ClientConfiguration.java
  2. 1 23
      config/src/main/java/org/springframework/security/config/annotation/web/reactive/ReactiveOAuth2ClientConfiguration.java
  3. 0 22
      config/src/main/java/org/springframework/security/config/http/OAuth2AuthorizedClientManagerRegistrar.java
  4. 1 91
      config/src/test/java/org/springframework/security/config/annotation/web/configuration/OAuth2AuthorizedClientManagerConfigurationTests.java
  5. 1 98
      config/src/test/java/org/springframework/security/config/annotation/web/reactive/ReactiveOAuth2AuthorizedClientManagerConfigurationTests.java
  6. 1 87
      config/src/test/java/org/springframework/security/config/http/OAuth2AuthorizedClientManagerRegistrarTests.java
  7. 1 7
      config/src/test/resources/org/springframework/security/config/http/OAuth2AuthorizedClientManagerRegistrarTests-clients.xml
  8. 1 7
      config/src/test/resources/org/springframework/security/config/http/OAuth2AuthorizedClientManagerRegistrarTests-providers.xml
  9. 2 258
      docs/modules/ROOT/pages/reactive/oauth2/client/authorization-grants.adoc
  10. 0 1
      docs/modules/ROOT/pages/reactive/oauth2/client/authorized-clients.adoc
  11. 18 24
      docs/modules/ROOT/pages/reactive/oauth2/client/core.adoc
  12. 1 4
      docs/modules/ROOT/pages/reactive/oauth2/client/index.adoc
  13. 0 33
      docs/modules/ROOT/pages/reactive/oauth2/index.adoc
  14. 2 324
      docs/modules/ROOT/pages/servlet/oauth2/client/authorization-grants.adoc
  15. 0 2
      docs/modules/ROOT/pages/servlet/oauth2/client/authorized-clients.adoc
  16. 18 24
      docs/modules/ROOT/pages/servlet/oauth2/client/core.adoc
  17. 1 4
      docs/modules/ROOT/pages/servlet/oauth2/client/index.adoc
  18. 0 33
      docs/modules/ROOT/pages/servlet/oauth2/index.adoc
  19. 1 13
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/OAuth2AuthorizationContext.java
  20. 4 111
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/OAuth2AuthorizedClientProviderBuilder.java
  21. 0 167
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordOAuth2AuthorizedClientProvider.java
  22. 0 161
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordReactiveOAuth2AuthorizedClientProvider.java
  23. 4 112
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ReactiveOAuth2AuthorizedClientProviderBuilder.java
  24. 1 2
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/AbstractWebClientReactiveOAuth2AccessTokenResponseClient.java
  25. 1 5
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultOAuth2TokenRequestParametersConverter.java
  26. 0 136
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultPasswordTokenResponseClient.java
  27. 0 100
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/OAuth2PasswordGrantRequest.java
  28. 0 63
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/OAuth2PasswordGrantRequestEntityConverter.java
  29. 0 49
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/WebClientReactivePasswordTokenResponseClient.java
  30. 0 3
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/jackson2/StdConverters.java
  31. 1 12
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistration.java
  32. 1 2
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManager.java
  33. 1 2
      oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManager.java
  34. 9 47
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/OAuth2AuthorizedClientProviderBuilderTests.java
  35. 0 240
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/PasswordOAuth2AuthorizedClientProviderTests.java
  36. 0 242
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/PasswordReactiveOAuth2AuthorizedClientProviderTests.java
  37. 1 45
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/ReactiveOAuth2AuthorizedClientProviderBuilderTests.java
  38. 1 25
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/DefaultOAuth2TokenRequestParametersConverterTests.java
  39. 0 317
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/DefaultPasswordTokenResponseClientTests.java
  40. 0 133
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/OAuth2PasswordGrantRequestEntityConverterTests.java
  41. 0 88
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/OAuth2PasswordGrantRequestTests.java
  42. 0 450
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactivePasswordTokenResponseClientTests.java
  43. 1 98
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/ClientRegistrationTests.java
  44. 1 14
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/TestClientRegistrations.java
  45. 1 42
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManagerTests.java
  46. 1 40
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManagerTests.java
  47. 2 62
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/method/annotation/OAuth2AuthorizedClientArgumentResolverTests.java
  48. 1 63
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServerOAuth2AuthorizedClientExchangeFilterFunctionTests.java
  49. 1 54
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunctionTests.java
  50. 3 12
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/AuthorizationGrantType.java
  51. 0 10
      oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/OAuth2ParameterNames.java
  52. 1 6
      oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/AuthorizationGrantTypeTests.java
  53. 9 3
      test/src/main/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurers.java
  54. 9 3
      test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java

+ 0 - 22
config/src/main/java/org/springframework/security/config/annotation/web/configuration/OAuth2ClientConfiguration.java

@@ -50,13 +50,11 @@ import org.springframework.security.oauth2.client.DelegatingOAuth2AuthorizedClie
 import org.springframework.security.oauth2.client.JwtBearerOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
-import org.springframework.security.oauth2.client.PasswordOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.RefreshTokenOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.TokenExchangeOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.endpoint.JwtBearerGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.TokenExchangeGrantRequest;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
@@ -173,7 +171,6 @@ final class OAuth2ClientConfiguration {
 				AuthorizationCodeOAuth2AuthorizedClientProvider.class,
 				RefreshTokenOAuth2AuthorizedClientProvider.class,
 				ClientCredentialsOAuth2AuthorizedClientProvider.class,
-				PasswordOAuth2AuthorizedClientProvider.class,
 				JwtBearerOAuth2AuthorizedClientProvider.class,
 				TokenExchangeOAuth2AuthorizedClientProvider.class
 		);
@@ -241,7 +238,6 @@ final class OAuth2ClientConfiguration {
 				authorizedClientProviders.add(getRefreshTokenAuthorizedClientProvider(authorizedClientProviderBeans));
 				authorizedClientProviders
 					.add(getClientCredentialsAuthorizedClientProvider(authorizedClientProviderBeans));
-				authorizedClientProviders.add(getPasswordAuthorizedClientProvider(authorizedClientProviderBeans));
 
 				OAuth2AuthorizedClientProvider jwtBearerAuthorizedClientProvider = getJwtBearerAuthorizedClientProvider(
 						authorizedClientProviderBeans);
@@ -331,24 +327,6 @@ final class OAuth2ClientConfiguration {
 			return authorizedClientProvider;
 		}
 
-		private OAuth2AuthorizedClientProvider getPasswordAuthorizedClientProvider(
-				Collection<OAuth2AuthorizedClientProvider> authorizedClientProviders) {
-			PasswordOAuth2AuthorizedClientProvider authorizedClientProvider = getAuthorizedClientProviderByType(
-					authorizedClientProviders, PasswordOAuth2AuthorizedClientProvider.class);
-			if (authorizedClientProvider == null) {
-				authorizedClientProvider = new PasswordOAuth2AuthorizedClientProvider();
-			}
-
-			OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient = getBeanOfType(
-					ResolvableType.forClassWithGenerics(OAuth2AccessTokenResponseClient.class,
-							OAuth2PasswordGrantRequest.class));
-			if (accessTokenResponseClient != null) {
-				authorizedClientProvider.setAccessTokenResponseClient(accessTokenResponseClient);
-			}
-
-			return authorizedClientProvider;
-		}
-
 		private OAuth2AuthorizedClientProvider getJwtBearerAuthorizedClientProvider(
 				Collection<OAuth2AuthorizedClientProvider> authorizedClientProviders) {
 			JwtBearerOAuth2AuthorizedClientProvider authorizedClientProvider = getAuthorizedClientProviderByType(

+ 1 - 23
config/src/main/java/org/springframework/security/config/annotation/web/reactive/ReactiveOAuth2ClientConfiguration.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -43,7 +43,6 @@ import org.springframework.security.oauth2.client.AuthorizationCodeReactiveOAuth
 import org.springframework.security.oauth2.client.ClientCredentialsReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.DelegatingReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.JwtBearerReactiveOAuth2AuthorizedClientProvider;
-import org.springframework.security.oauth2.client.PasswordReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService;
@@ -51,7 +50,6 @@ import org.springframework.security.oauth2.client.RefreshTokenReactiveOAuth2Auth
 import org.springframework.security.oauth2.client.TokenExchangeReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.endpoint.JwtBearerGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.TokenExchangeGrantRequest;
@@ -137,7 +135,6 @@ final class ReactiveOAuth2ClientConfiguration {
 				AuthorizationCodeReactiveOAuth2AuthorizedClientProvider.class,
 				RefreshTokenReactiveOAuth2AuthorizedClientProvider.class,
 				ClientCredentialsReactiveOAuth2AuthorizedClientProvider.class,
-				PasswordReactiveOAuth2AuthorizedClientProvider.class,
 				JwtBearerReactiveOAuth2AuthorizedClientProvider.class,
 				TokenExchangeReactiveOAuth2AuthorizedClientProvider.class
 		);
@@ -212,7 +209,6 @@ final class ReactiveOAuth2ClientConfiguration {
 				authorizedClientProviders.add(getRefreshTokenAuthorizedClientProvider(authorizedClientProviderBeans));
 				authorizedClientProviders
 					.add(getClientCredentialsAuthorizedClientProvider(authorizedClientProviderBeans));
-				authorizedClientProviders.add(getPasswordAuthorizedClientProvider(authorizedClientProviderBeans));
 
 				ReactiveOAuth2AuthorizedClientProvider jwtBearerAuthorizedClientProvider = getJwtBearerAuthorizedClientProvider(
 						authorizedClientProviderBeans);
@@ -301,24 +297,6 @@ final class ReactiveOAuth2ClientConfiguration {
 			return authorizedClientProvider;
 		}
 
-		private ReactiveOAuth2AuthorizedClientProvider getPasswordAuthorizedClientProvider(
-				Collection<ReactiveOAuth2AuthorizedClientProvider> authorizedClientProviders) {
-			PasswordReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = getAuthorizedClientProviderByType(
-					authorizedClientProviders, PasswordReactiveOAuth2AuthorizedClientProvider.class);
-			if (authorizedClientProvider == null) {
-				authorizedClientProvider = new PasswordReactiveOAuth2AuthorizedClientProvider();
-			}
-
-			ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient = getBeanOfType(
-					ResolvableType.forClassWithGenerics(ReactiveOAuth2AccessTokenResponseClient.class,
-							OAuth2PasswordGrantRequest.class));
-			if (accessTokenResponseClient != null) {
-				authorizedClientProvider.setAccessTokenResponseClient(accessTokenResponseClient);
-			}
-
-			return authorizedClientProvider;
-		}
-
 		private ReactiveOAuth2AuthorizedClientProvider getJwtBearerAuthorizedClientProvider(
 				Collection<ReactiveOAuth2AuthorizedClientProvider> authorizedClientProviders) {
 			JwtBearerReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = getAuthorizedClientProviderByType(

+ 0 - 22
config/src/main/java/org/springframework/security/config/http/OAuth2AuthorizedClientManagerRegistrar.java

@@ -43,13 +43,11 @@ import org.springframework.security.oauth2.client.DelegatingOAuth2AuthorizedClie
 import org.springframework.security.oauth2.client.JwtBearerOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
-import org.springframework.security.oauth2.client.PasswordOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.RefreshTokenOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.TokenExchangeOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.endpoint.JwtBearerGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.TokenExchangeGrantRequest;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
@@ -78,7 +76,6 @@ final class OAuth2AuthorizedClientManagerRegistrar implements BeanDefinitionRegi
 			AuthorizationCodeOAuth2AuthorizedClientProvider.class,
 			RefreshTokenOAuth2AuthorizedClientProvider.class,
 			ClientCredentialsOAuth2AuthorizedClientProvider.class,
-			PasswordOAuth2AuthorizedClientProvider.class,
 			JwtBearerOAuth2AuthorizedClientProvider.class,
 			TokenExchangeOAuth2AuthorizedClientProvider.class
 	);
@@ -133,7 +130,6 @@ final class OAuth2AuthorizedClientManagerRegistrar implements BeanDefinitionRegi
 			authorizedClientProviders.add(getAuthorizationCodeAuthorizedClientProvider(authorizedClientProviderBeans));
 			authorizedClientProviders.add(getRefreshTokenAuthorizedClientProvider(authorizedClientProviderBeans));
 			authorizedClientProviders.add(getClientCredentialsAuthorizedClientProvider(authorizedClientProviderBeans));
-			authorizedClientProviders.add(getPasswordAuthorizedClientProvider(authorizedClientProviderBeans));
 
 			OAuth2AuthorizedClientProvider jwtBearerAuthorizedClientProvider = getJwtBearerAuthorizedClientProvider(
 					authorizedClientProviderBeans);
@@ -225,24 +221,6 @@ final class OAuth2AuthorizedClientManagerRegistrar implements BeanDefinitionRegi
 		return authorizedClientProvider;
 	}
 
-	private OAuth2AuthorizedClientProvider getPasswordAuthorizedClientProvider(
-			Collection<OAuth2AuthorizedClientProvider> authorizedClientProviders) {
-		PasswordOAuth2AuthorizedClientProvider authorizedClientProvider = getAuthorizedClientProviderByType(
-				authorizedClientProviders, PasswordOAuth2AuthorizedClientProvider.class);
-		if (authorizedClientProvider == null) {
-			authorizedClientProvider = new PasswordOAuth2AuthorizedClientProvider();
-		}
-
-		OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient = getBeanOfType(
-				ResolvableType.forClassWithGenerics(OAuth2AccessTokenResponseClient.class,
-						OAuth2PasswordGrantRequest.class));
-		if (accessTokenResponseClient != null) {
-			authorizedClientProvider.setAccessTokenResponseClient(accessTokenResponseClient);
-		}
-
-		return authorizedClientProvider;
-	}
-
 	private OAuth2AuthorizedClientProvider getJwtBearerAuthorizedClientProvider(
 			Collection<OAuth2AuthorizedClientProvider> authorizedClientProviders) {
 		JwtBearerOAuth2AuthorizedClientProvider authorizedClientProvider = getAuthorizedClientProviderByType(

+ 1 - 91
config/src/test/java/org/springframework/security/config/annotation/web/configuration/OAuth2AuthorizedClientManagerConfigurationTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -20,11 +20,7 @@ import java.time.Duration;
 import java.time.Instant;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Consumer;
 
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
@@ -48,7 +44,6 @@ 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.OAuth2AuthorizedClientManager;
-import org.springframework.security.oauth2.client.PasswordOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.RefreshTokenOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.TokenExchangeOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.endpoint.AbstractOAuth2AuthorizationGrantRequest;
@@ -56,13 +51,11 @@ import org.springframework.security.oauth2.client.endpoint.JwtBearerGrantRequest
 import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.TokenExchangeGrantRequest;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
-import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.core.AuthorizationGrantType;
 import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
@@ -71,13 +64,11 @@ import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
 import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
 import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses;
 import org.springframework.security.oauth2.jwt.JoseHeaderNames;
 import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.JwtClaimNames;
 import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
-import org.springframework.util.StringUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -237,50 +228,6 @@ public class OAuth2AuthorizedClientManagerConfigurationTests {
 		assertThat(grantRequest.getGrantType()).isEqualTo(AuthorizationGrantType.CLIENT_CREDENTIALS);
 	}
 
-	@Test
-	public void authorizeWhenPasswordAccessTokenResponseClientBeanThenUsed() {
-		this.spring.register(CustomAccessTokenResponseClientsConfig.class).autowire();
-		testPasswordGrant();
-	}
-
-	@Test
-	public void authorizeWhenPasswordAuthorizedClientProviderBeanThenUsed() {
-		this.spring.register(CustomAuthorizedClientProvidersConfig.class).autowire();
-		testPasswordGrant();
-	}
-
-	private void testPasswordGrant() {
-		OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
-		given(MOCK_RESPONSE_CLIENT.getTokenResponse(any(OAuth2PasswordGrantRequest.class)))
-			.willReturn(accessTokenResponse);
-
-		TestingAuthenticationToken authentication = new TestingAuthenticationToken("user", "password");
-		ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId("facebook");
-		// @formatter:off
-		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest
-				.withClientRegistrationId(clientRegistration.getRegistrationId())
-				.principal(authentication)
-				.attribute(HttpServletRequest.class.getName(), this.request)
-				.attribute(HttpServletResponse.class.getName(), this.response)
-				.build();
-		// @formatter:on
-		this.request.setParameter(OAuth2ParameterNames.USERNAME, "user");
-		this.request.setParameter(OAuth2ParameterNames.PASSWORD, "password");
-		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
-		assertThat(authorizedClient).isNotNull();
-
-		ArgumentCaptor<OAuth2PasswordGrantRequest> grantRequestCaptor = ArgumentCaptor
-			.forClass(OAuth2PasswordGrantRequest.class);
-		verify(MOCK_RESPONSE_CLIENT).getTokenResponse(grantRequestCaptor.capture());
-
-		OAuth2PasswordGrantRequest grantRequest = grantRequestCaptor.getValue();
-		assertThat(grantRequest.getClientRegistration().getRegistrationId())
-			.isEqualTo(clientRegistration.getRegistrationId());
-		assertThat(grantRequest.getGrantType()).isEqualTo(AuthorizationGrantType.PASSWORD);
-		assertThat(grantRequest.getUsername()).isEqualTo("user");
-		assertThat(grantRequest.getPassword()).isEqualTo("password");
-	}
-
 	@Test
 	public void authorizeWhenJwtBearerAccessTokenResponseClientBeanThenUsed() {
 		this.spring.register(CustomAccessTokenResponseClientsConfig.class).autowire();
@@ -400,11 +347,6 @@ public class OAuth2AuthorizedClientManagerConfigurationTests {
 			return new MockAccessTokenResponseClient<>();
 		}
 
-		@Bean
-		OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> passwordTokenResponseClient() {
-			return new MockAccessTokenResponseClient<>();
-		}
-
 		@Bean
 		OAuth2AccessTokenResponseClient<JwtBearerGrantRequest> jwtBearerTokenResponseClient() {
 			return new MockAccessTokenResponseClient<>();
@@ -440,13 +382,6 @@ public class OAuth2AuthorizedClientManagerConfigurationTests {
 			return authorizedClientProvider;
 		}
 
-		@Bean
-		PasswordOAuth2AuthorizedClientProvider passwordProvider() {
-			PasswordOAuth2AuthorizedClientProvider authorizedClientProvider = new PasswordOAuth2AuthorizedClientProvider();
-			authorizedClientProvider.setAccessTokenResponseClient(new MockAccessTokenResponseClient<>());
-			return authorizedClientProvider;
-		}
-
 		@Bean
 		JwtBearerOAuth2AuthorizedClientProvider jwtBearerAuthorizedClientProvider() {
 			JwtBearerOAuth2AuthorizedClientProvider authorizedClientProvider = new JwtBearerOAuth2AuthorizedClientProvider();
@@ -479,11 +414,6 @@ public class OAuth2AuthorizedClientManagerConfigurationTests {
 							.clientSecret("github-client-secret")
 							.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
 							.build(),
-					CommonOAuth2Provider.FACEBOOK.getBuilder("facebook")
-							.clientId("facebook-client-id")
-							.clientSecret("facebook-client-secret")
-							.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-							.build(),
 					CommonOAuth2Provider.OKTA.getBuilder("okta")
 							.clientId("okta-client-id")
 							.clientSecret("okta-client-secret")
@@ -505,26 +435,6 @@ public class OAuth2AuthorizedClientManagerConfigurationTests {
 			return mock(OAuth2AuthorizedClientRepository.class);
 		}
 
-		@Bean
-		Consumer<DefaultOAuth2AuthorizedClientManager> authorizedClientManagerConsumer() {
-			return (authorizedClientManager) -> authorizedClientManager
-				.setContextAttributesMapper((authorizeRequest) -> {
-					HttpServletRequest request = Objects
-						.requireNonNull(authorizeRequest.getAttribute(HttpServletRequest.class.getName()));
-					String username = request.getParameter(OAuth2ParameterNames.USERNAME);
-					String password = request.getParameter(OAuth2ParameterNames.PASSWORD);
-
-					Map<String, Object> attributes = Collections.emptyMap();
-					if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
-						attributes = new HashMap<>();
-						attributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-						attributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
-					}
-
-					return attributes;
-				});
-		}
-
 	}
 
 	private static class MockAccessTokenResponseClient<T extends AbstractOAuth2AuthorizationGrantRequest>

+ 1 - 98
config/src/test/java/org/springframework/security/config/annotation/web/reactive/ReactiveOAuth2AuthorizedClientManagerConfigurationTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -20,11 +20,7 @@ import java.time.Duration;
 import java.time.Instant;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Consumer;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -34,7 +30,6 @@ import reactor.core.publisher.Mono;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.http.MediaType;
 import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
 import org.springframework.mock.web.server.MockServerWebExchange;
 import org.springframework.security.authentication.TestingAuthenticationToken;
@@ -47,7 +42,6 @@ import org.springframework.security.oauth2.client.JwtBearerReactiveOAuth2Authori
 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.PasswordReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService;
 import org.springframework.security.oauth2.client.RefreshTokenReactiveOAuth2AuthorizedClientProvider;
@@ -56,14 +50,12 @@ import org.springframework.security.oauth2.client.endpoint.AbstractOAuth2Authori
 import org.springframework.security.oauth2.client.endpoint.JwtBearerGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.TokenExchangeGrantRequest;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
-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.WebSessionServerOAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.core.AuthorizationGrantType;
@@ -73,13 +65,11 @@ import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
 import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
 import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses;
 import org.springframework.security.oauth2.jwt.JoseHeaderNames;
 import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.JwtClaimNames;
 import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
-import org.springframework.util.StringUtils;
 import org.springframework.web.server.ServerWebExchange;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -265,53 +255,6 @@ public class ReactiveOAuth2AuthorizedClientManagerConfigurationTests {
 		assertThat(grantRequest.getGrantType()).isEqualTo(AuthorizationGrantType.CLIENT_CREDENTIALS);
 	}
 
-	@Test
-	public void authorizeWhenPasswordAccessTokenResponseClientBeanThenUsed() {
-		this.spring.register(CustomAccessTokenResponseClientsConfig.class).autowire();
-		testPasswordGrant();
-	}
-
-	@Test
-	public void authorizeWhenPasswordAuthorizedClientProviderBeanThenUsed() {
-		this.spring.register(CustomAuthorizedClientProvidersConfig.class).autowire();
-		testPasswordGrant();
-	}
-
-	private void testPasswordGrant() {
-		OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
-		given(MOCK_RESPONSE_CLIENT.getTokenResponse(any(OAuth2PasswordGrantRequest.class)))
-			.willReturn(Mono.just(accessTokenResponse));
-
-		TestingAuthenticationToken authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER");
-		ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId("facebook")
-			.block();
-		assertThat(clientRegistration).isNotNull();
-		MockServerHttpRequest request = MockServerHttpRequest.post("/")
-			.contentType(MediaType.APPLICATION_FORM_URLENCODED)
-			.body("username=user&password=password");
-		this.exchange = MockServerWebExchange.builder(request).build();
-		// @formatter:off
-		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest
-				.withClientRegistrationId(clientRegistration.getRegistrationId())
-				.principal(authentication)
-				.attribute(ServerWebExchange.class.getName(), this.exchange)
-				.build();
-		// @formatter:on
-		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest).block();
-		assertThat(authorizedClient).isNotNull();
-
-		ArgumentCaptor<OAuth2PasswordGrantRequest> grantRequestCaptor = ArgumentCaptor
-			.forClass(OAuth2PasswordGrantRequest.class);
-		verify(MOCK_RESPONSE_CLIENT).getTokenResponse(grantRequestCaptor.capture());
-
-		OAuth2PasswordGrantRequest grantRequest = grantRequestCaptor.getValue();
-		assertThat(grantRequest.getClientRegistration().getRegistrationId())
-			.isEqualTo(clientRegistration.getRegistrationId());
-		assertThat(grantRequest.getGrantType()).isEqualTo(AuthorizationGrantType.PASSWORD);
-		assertThat(grantRequest.getUsername()).isEqualTo("user");
-		assertThat(grantRequest.getPassword()).isEqualTo("password");
-	}
-
 	@Test
 	public void authorizeWhenJwtBearerAccessTokenResponseClientBeanThenUsed() {
 		this.spring.register(CustomAccessTokenResponseClientsConfig.class).autowire();
@@ -451,11 +394,6 @@ public class ReactiveOAuth2AuthorizedClientManagerConfigurationTests {
 			return new MockAccessTokenResponseClient<>();
 		}
 
-		@Bean
-		ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> passwordAccessTokenResponseClient() {
-			return new MockAccessTokenResponseClient<>();
-		}
-
 		@Bean
 		ReactiveOAuth2AccessTokenResponseClient<JwtBearerGrantRequest> jwtBearerAccessTokenResponseClient() {
 			return new MockAccessTokenResponseClient<>();
@@ -491,13 +429,6 @@ public class ReactiveOAuth2AuthorizedClientManagerConfigurationTests {
 			return authorizedClientProvider;
 		}
 
-		@Bean
-		PasswordReactiveOAuth2AuthorizedClientProvider password() {
-			PasswordReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = new PasswordReactiveOAuth2AuthorizedClientProvider();
-			authorizedClientProvider.setAccessTokenResponseClient(new MockAccessTokenResponseClient<>());
-			return authorizedClientProvider;
-		}
-
 		@Bean
 		JwtBearerReactiveOAuth2AuthorizedClientProvider jwtBearer() {
 			JwtBearerReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = new JwtBearerReactiveOAuth2AuthorizedClientProvider();
@@ -530,11 +461,6 @@ public class ReactiveOAuth2AuthorizedClientManagerConfigurationTests {
 						.clientSecret("github-client-secret")
 						.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
 						.build(),
-					CommonOAuth2Provider.FACEBOOK.getBuilder("facebook")
-						.clientId("facebook-client-id")
-						.clientSecret("facebook-client-secret")
-						.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-						.build(),
 					CommonOAuth2Provider.OKTA.getBuilder("okta")
 						.clientId("okta-client-id")
 						.clientSecret("okta-client-secret")
@@ -551,29 +477,6 @@ public class ReactiveOAuth2AuthorizedClientManagerConfigurationTests {
 			// @formatter:on
 		}
 
-		@Bean
-		Consumer<DefaultReactiveOAuth2AuthorizedClientManager> authorizedClientManagerConsumer() {
-			return (authorizedClientManager) -> authorizedClientManager
-				.setContextAttributesMapper((authorizeRequest) -> {
-					ServerWebExchange exchange = Objects
-						.requireNonNull(authorizeRequest.getAttribute(ServerWebExchange.class.getName()));
-					return exchange.getFormData().map((parameters) -> {
-						String username = parameters.getFirst(OAuth2ParameterNames.USERNAME);
-						String password = parameters.getFirst(OAuth2ParameterNames.PASSWORD);
-
-						Map<String, Object> attributes = Collections.emptyMap();
-						if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
-							attributes = new HashMap<>();
-							attributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-							attributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
-						}
-
-						return attributes;
-					});
-				});
-
-		}
-
 	}
 
 	private static class MockAccessTokenResponseClient<T extends AbstractOAuth2AuthorizationGrantRequest>

+ 1 - 87
config/src/test/java/org/springframework/security/config/http/OAuth2AuthorizedClientManagerRegistrarTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -20,12 +20,8 @@ import java.time.Duration;
 import java.time.Instant;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Consumer;
 
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
@@ -47,19 +43,16 @@ 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.OAuth2AuthorizedClientManager;
-import org.springframework.security.oauth2.client.PasswordOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.RefreshTokenOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.TokenExchangeOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.endpoint.AbstractOAuth2AuthorizationGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.JwtBearerGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.TokenExchangeGrantRequest;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
-import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.core.AuthorizationGrantType;
 import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
@@ -68,13 +61,11 @@ import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
 import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
 import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses;
 import org.springframework.security.oauth2.jwt.JoseHeaderNames;
 import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.JwtClaimNames;
 import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
-import org.springframework.util.StringUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -235,50 +226,6 @@ public class OAuth2AuthorizedClientManagerRegistrarTests {
 		assertThat(grantRequest.getGrantType()).isEqualTo(AuthorizationGrantType.CLIENT_CREDENTIALS);
 	}
 
-	@Test
-	public void authorizeWhenPasswordAccessTokenResponseClientBeanThenUsed() {
-		this.spring.configLocations(xml("clients")).autowire();
-		testPasswordGrant();
-	}
-
-	@Test
-	public void authorizeWhenPasswordAuthorizedClientProviderBeanThenUsed() {
-		this.spring.configLocations(xml("providers")).autowire();
-		testPasswordGrant();
-	}
-
-	private void testPasswordGrant() {
-		OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
-		given(MOCK_RESPONSE_CLIENT.getTokenResponse(any(OAuth2PasswordGrantRequest.class)))
-			.willReturn(accessTokenResponse);
-
-		TestingAuthenticationToken authentication = new TestingAuthenticationToken("user", "password");
-		ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId("facebook");
-		// @formatter:off
-		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest
-				.withClientRegistrationId(clientRegistration.getRegistrationId())
-				.principal(authentication)
-				.attribute(HttpServletRequest.class.getName(), this.request)
-				.attribute(HttpServletResponse.class.getName(), this.response)
-				.build();
-		// @formatter:on
-		this.request.setParameter(OAuth2ParameterNames.USERNAME, "user");
-		this.request.setParameter(OAuth2ParameterNames.PASSWORD, "password");
-		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
-		assertThat(authorizedClient).isNotNull();
-
-		ArgumentCaptor<OAuth2PasswordGrantRequest> grantRequestCaptor = ArgumentCaptor
-			.forClass(OAuth2PasswordGrantRequest.class);
-		verify(MOCK_RESPONSE_CLIENT).getTokenResponse(grantRequestCaptor.capture());
-
-		OAuth2PasswordGrantRequest grantRequest = grantRequestCaptor.getValue();
-		assertThat(grantRequest.getClientRegistration().getRegistrationId())
-			.isEqualTo(clientRegistration.getRegistrationId());
-		assertThat(grantRequest.getGrantType()).isEqualTo(AuthorizationGrantType.PASSWORD);
-		assertThat(grantRequest.getUsername()).isEqualTo("user");
-		assertThat(grantRequest.getPassword()).isEqualTo("password");
-	}
-
 	@Test
 	public void authorizeWhenJwtBearerAccessTokenResponseClientBeanThenUsed() {
 		this.spring.configLocations(xml("clients")).autowire();
@@ -390,11 +337,6 @@ public class OAuth2AuthorizedClientManagerRegistrarTests {
 						.clientSecret("github-client-secret")
 						.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
 						.build(),
-				CommonOAuth2Provider.FACEBOOK.getBuilder("facebook")
-						.clientId("facebook-client-id")
-						.clientSecret("facebook-client-secret")
-						.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-						.build(),
 				CommonOAuth2Provider.OKTA.getBuilder("okta")
 						.clientId("okta-client-id")
 						.clientSecret("okta-client-secret")
@@ -411,24 +353,6 @@ public class OAuth2AuthorizedClientManagerRegistrarTests {
 		// @formatter:on
 	}
 
-	public static Consumer<DefaultOAuth2AuthorizedClientManager> authorizedClientManagerConsumer() {
-		return (authorizedClientManager) -> authorizedClientManager.setContextAttributesMapper((authorizeRequest) -> {
-			HttpServletRequest request = Objects
-				.requireNonNull(authorizeRequest.getAttribute(HttpServletRequest.class.getName()));
-			String username = request.getParameter(OAuth2ParameterNames.USERNAME);
-			String password = request.getParameter(OAuth2ParameterNames.PASSWORD);
-
-			Map<String, Object> attributes = Collections.emptyMap();
-			if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
-				attributes = new HashMap<>();
-				attributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-				attributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
-			}
-
-			return attributes;
-		});
-	}
-
 	public static AuthorizationCodeOAuth2AuthorizedClientProvider authorizationCode() {
 		return spy(new AuthorizationCodeOAuth2AuthorizedClientProvider());
 	}
@@ -453,16 +377,6 @@ public class OAuth2AuthorizedClientManagerRegistrarTests {
 		return new MockAccessTokenResponseClient<>();
 	}
 
-	public static PasswordOAuth2AuthorizedClientProvider password() {
-		PasswordOAuth2AuthorizedClientProvider authorizedClientProvider = new PasswordOAuth2AuthorizedClientProvider();
-		authorizedClientProvider.setAccessTokenResponseClient(passwordAccessTokenResponseClient());
-		return authorizedClientProvider;
-	}
-
-	public static OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> passwordAccessTokenResponseClient() {
-		return new MockAccessTokenResponseClient<>();
-	}
-
 	public static JwtBearerOAuth2AuthorizedClientProvider jwtBearer() {
 		JwtBearerOAuth2AuthorizedClientProvider authorizedClientProvider = new JwtBearerOAuth2AuthorizedClientProvider();
 		authorizedClientProvider.setAccessTokenResponseClient(jwtBearerAccessTokenResponseClient());

+ 1 - 7
config/src/test/resources/org/springframework/security/config/http/OAuth2AuthorizedClientManagerRegistrarTests-clients.xml

@@ -38,22 +38,16 @@
 		</b:constructor-arg>
 	</b:bean>
 
-	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
-			factory-method="authorizedClientManagerConsumer"/>
-
 	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
 			factory-method="refreshTokenAccessTokenResponseClient"/>
 
 	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
 			factory-method="clientCredentialsAccessTokenResponseClient"/>
 
-	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
-			factory-method="passwordAccessTokenResponseClient"/>
-
 	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
 			factory-method="jwtBearerAccessTokenResponseClient"/>
 
 	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
 			factory-method="tokenExchangeAccessTokenResponseClient"/>
 
-</b:beans>
+</b:beans>

+ 1 - 7
config/src/test/resources/org/springframework/security/config/http/OAuth2AuthorizedClientManagerRegistrarTests-providers.xml

@@ -38,9 +38,6 @@
 		</b:constructor-arg>
 	</b:bean>
 
-	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
-			factory-method="authorizedClientManagerConsumer"/>
-
 	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
 			factory-method="authorizationCode"/>
 
@@ -50,13 +47,10 @@
 	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
 			factory-method="clientCredentials"/>
 
-	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
-			factory-method="password"/>
-
 	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
 			factory-method="jwtBearer"/>
 
 	<b:bean class="org.springframework.security.config.http.OAuth2AuthorizedClientManagerRegistrarTests"
 			factory-method="tokenExchange"/>
 
-</b:beans>
+</b:beans>

+ 2 - 258
docs/modules/ROOT/pages/reactive/oauth2/client/authorization-grants.adoc

@@ -493,7 +493,7 @@ authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
 which is an implementation of a `ReactiveOAuth2AuthorizedClientProvider` for the Refresh Token grant.
 ====
 
-The `OAuth2RefreshToken` may optionally be returned in the Access Token Response for the `authorization_code` and `password` grant types.
+The `OAuth2RefreshToken` may optionally be returned in the Access Token Response for the `authorization_code` grant type.
 If the `OAuth2AuthorizedClient.getRefreshToken()` is available and the `OAuth2AuthorizedClient.getAccessToken()` is expired, it will automatically be refreshed by the `RefreshTokenReactiveOAuth2AuthorizedClientProvider`.
 
 [[oauth2-client-client-credentials]]
@@ -698,264 +698,8 @@ class OAuth2ClientController {
 If not provided, it will be obtained from the https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context] via the key `ServerWebExchange.class`.
 ====
 
-[[oauth2-client-password]]
-== [[oauth2Client-password-grant]]Resource Owner Password Credentials
-
-[NOTE]
-====
-Please refer to the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.3[Resource Owner Password Credentials] grant.
-====
-
-[[oauth2-client-password-access-token]]
-=== Requesting an Access Token
-
-[NOTE]
-====
-Please refer to the https://tools.ietf.org/html/rfc6749#section-4.3.2[Access Token Request/Response] protocol flow for the Resource Owner Password Credentials grant.
-====
-
-The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Resource Owner Password Credentials grant is `WebClientReactivePasswordTokenResponseClient`, which uses a `WebClient` when requesting an access token at the Authorization Server’s Token Endpoint.
-
-[CAUTION]
-====
-The `WebClientReactivePasswordTokenResponseClient` class and support for the Resource Owner Password Credentials grant are deprecated.
-This section will be removed in Spring Security 7.
-====
-
-:section-id: password
-:grant-type: Password
-:class-name: WebClientReactivePasswordTokenResponseClient
-:grant-request: OAuth2PasswordGrantRequest
-:leveloffset: +1
-include::partial$reactive/oauth2/client/web-client-access-token-response-client.adoc[]
-
-:leveloffset: -1
-
-[[oauth2-client-password-authorized-client-provider-builder]]
-=== Customize using the Builder
-
-Whether you customize `WebClientReactivePasswordTokenResponseClient` or provide your own implementation of `ReactiveOAuth2AccessTokenResponseClient`, you can configure it using the `ReactiveOAuth2AuthorizedClientProviderBuilder` (as an alternative to <<oauth2-client-password-access-token-response-client-bean,publishing a bean>>) as follows:
-
-.Access Token Response Configuration via Builder
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-// Customize
-ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> passwordTokenResponseClient = ...
-
-ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
-		ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
-				.password((configurer) -> configurer.accessTokenResponseClient(passwordTokenResponseClient))
-				.refreshToken()
-				.build();
-
-// ...
-
-authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val passwordTokenResponseClient: ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> = ...
-
-val authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
-        .password { it.accessTokenResponseClient(passwordTokenResponseClient) }
-        .refreshToken()
-        .build()
-
-// ...
-
-authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
-----
-======
-
-[NOTE]
-====
-`ReactiveOAuth2AuthorizedClientProviderBuilder.builder().password()` configures a `PasswordReactiveOAuth2AuthorizedClientProvider`,
-which is an implementation of a `ReactiveOAuth2AuthorizedClientProvider` for the Resource Owner Password Credentials grant.
-====
-
-[[oauth2-client-password-authorized-client-manager]]
-=== Using the Access Token
-
-Given the following Spring Boot properties for an OAuth 2.0 Client registration:
-
-[source,yaml]
-----
-spring:
-  security:
-    oauth2:
-      client:
-        registration:
-          okta:
-            client-id: okta-client-id
-            client-secret: okta-client-secret
-            authorization-grant-type: password
-            scope: read, write
-        provider:
-          okta:
-            token-uri: https://dev-1234.oktapreview.com/oauth2/v1/token
-----
-
-...and the `ReactiveOAuth2AuthorizedClientManager` `@Bean`:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Bean
-public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
-		ReactiveClientRegistrationRepository clientRegistrationRepository,
-		ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
-
-	ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
-			ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
-					.password()
-					.refreshToken()
-					.build();
-
-	DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager =
-			new DefaultReactiveOAuth2AuthorizedClientManager(
-					clientRegistrationRepository, authorizedClientRepository);
-	authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
-
-	// Assuming the `username` and `password` are supplied as `ServerHttpRequest` parameters,
-	// map the `ServerHttpRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
-	authorizedClientManager.setContextAttributesMapper(contextAttributesMapper());
-
-	return authorizedClientManager;
-}
-
-private Function<OAuth2AuthorizeRequest, Mono<Map<String, Object>>> contextAttributesMapper() {
-	return authorizeRequest -> {
-		Map<String, Object> contextAttributes = Collections.emptyMap();
-		ServerWebExchange exchange = authorizeRequest.getAttribute(ServerWebExchange.class.getName());
-		ServerHttpRequest request = exchange.getRequest();
-		String username = request.getQueryParams().getFirst(OAuth2ParameterNames.USERNAME);
-		String password = request.getQueryParams().getFirst(OAuth2ParameterNames.PASSWORD);
-		if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
-			contextAttributes = new HashMap<>();
-
-			// `PasswordReactiveOAuth2AuthorizedClientProvider` requires both attributes
-			contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-			contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
-		}
-		return Mono.just(contextAttributes);
-	};
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Bean
-fun authorizedClientManager(
-        clientRegistrationRepository: ReactiveClientRegistrationRepository,
-        authorizedClientRepository: ServerOAuth2AuthorizedClientRepository): ReactiveOAuth2AuthorizedClientManager {
-    val authorizedClientProvider: ReactiveOAuth2AuthorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
-            .password()
-            .refreshToken()
-            .build()
-    val authorizedClientManager = DefaultReactiveOAuth2AuthorizedClientManager(
-            clientRegistrationRepository, authorizedClientRepository)
-    authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
-
-    // Assuming the `username` and `password` are supplied as `ServerHttpRequest` parameters,
-    // map the `ServerHttpRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
-    authorizedClientManager.setContextAttributesMapper(contextAttributesMapper())
-    return authorizedClientManager
-}
-
-private fun contextAttributesMapper(): Function<OAuth2AuthorizeRequest, Mono<MutableMap<String, Any>>> {
-    return Function { authorizeRequest ->
-        var contextAttributes: MutableMap<String, Any> = mutableMapOf()
-        val exchange: ServerWebExchange = authorizeRequest.getAttribute(ServerWebExchange::class.java.name)!!
-        val request: ServerHttpRequest = exchange.request
-        val username: String? = request.queryParams.getFirst(OAuth2ParameterNames.USERNAME)
-        val password: String? = request.queryParams.getFirst(OAuth2ParameterNames.PASSWORD)
-        if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
-            contextAttributes = hashMapOf()
-
-            // `PasswordReactiveOAuth2AuthorizedClientProvider` requires both attributes
-            contextAttributes[OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME] = username!!
-            contextAttributes[OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME] = password!!
-        }
-        Mono.just(contextAttributes)
-    }
-}
-----
-======
-
-You may obtain the `OAuth2AccessToken` as follows:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Controller
-public class OAuth2ClientController {
-
-	@Autowired
-	private ReactiveOAuth2AuthorizedClientManager authorizedClientManager;
-
-	@GetMapping("/")
-	public Mono<String> index(Authentication authentication, ServerWebExchange exchange) {
-		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("okta")
-				.principal(authentication)
-				.attribute(ServerWebExchange.class.getName(), exchange)
-				.build();
-
-		return this.authorizedClientManager.authorize(authorizeRequest)
-				.map(OAuth2AuthorizedClient::getAccessToken)
-				// ...
-				.thenReturn("index");
-	}
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Controller
-class OAuth2ClientController {
-    @Autowired
-    private lateinit var authorizedClientManager: ReactiveOAuth2AuthorizedClientManager
-
-    @GetMapping("/")
-    fun index(authentication: Authentication, exchange: ServerWebExchange): Mono<String> {
-        val authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("okta")
-                .principal(authentication)
-                .attribute(ServerWebExchange::class.java.name, exchange)
-                .build()
-
-        return authorizedClientManager.authorize(authorizeRequest)
-                .map { it.accessToken }
-                // ...
-                .thenReturn("index")
-    }
-}
-----
-======
-
-[NOTE]
-====
-`ServerWebExchange` is an OPTIONAL attribute.
-If not provided, it will be obtained from the https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context] via the key `ServerWebExchange.class`.
-====
-
 [[oauth2-client-jwt-bearer]]
-== [[oauth2Client-jwt-bearer-grant]]JWT Bearer
+== JWT Bearer
 
 [NOTE]
 ====

+ 0 - 1
docs/modules/ROOT/pages/reactive/oauth2/client/authorized-clients.adoc

@@ -56,7 +56,6 @@ It directly uses an xref:reactive/oauth2/client/core.adoc#oauth2Client-authorize
 * An `OAuth2AccessToken` will be requested if the client has not yet been authorized.
 ** `authorization_code` - triggers the Authorization Request redirect to initiate the flow
 ** `client_credentials` - the access token is obtained directly from the Token Endpoint
-** `password` - the access token is obtained directly from the Token Endpoint
 * If the `OAuth2AccessToken` is expired, it will be refreshed (or renewed) if a `ReactiveOAuth2AuthorizedClientProvider` is available to perform the authorization
 
 The following code shows an example of how to configure `WebClient` with OAuth 2.0 Client support:

+ 18 - 24
docs/modules/ROOT/pages/reactive/oauth2/client/core.adoc

@@ -51,7 +51,7 @@ public final class ClientRegistration {
 <4> `clientAuthenticationMethod`: The method used to authenticate the Client with the Provider.
 The supported values are *client_secret_basic*, *client_secret_post*, *private_key_jwt*, *client_secret_jwt* and *none* https://tools.ietf.org/html/rfc6749#section-2.1[(public clients)].
 <5> `authorizationGrantType`: The OAuth 2.0 Authorization Framework defines four https://tools.ietf.org/html/rfc6749#section-1.3[Authorization Grant] types.
- The supported values are `authorization_code`, `client_credentials`, `password`, as well as, extension grant type `urn:ietf:params:oauth:grant-type:jwt-bearer`.
+ The supported values are `authorization_code`, `client_credentials`, as well as, extension grant type `urn:ietf:params:oauth:grant-type:jwt-bearer`.
 <6> `redirectUri`: The client's registered redirect URI that the _Authorization Server_ redirects the end-user's user-agent
  to after the end-user has authenticated and authorized access to the client.
 <7> `scopes`: The scope(s) requested by the client during the Authorization Request flow, such as openid, email, or profile.
@@ -255,7 +255,7 @@ Implementations will typically implement an authorization grant type, eg. `autho
 The default implementation of `ReactiveOAuth2AuthorizedClientManager` is `DefaultReactiveOAuth2AuthorizedClientManager`, which is associated with a `ReactiveOAuth2AuthorizedClientProvider` that may support multiple authorization grant types using a delegation-based composite.
 The `ReactiveOAuth2AuthorizedClientProviderBuilder` may be used to configure and build the delegation-based composite.
 
-The following code shows an example of how to configure and build a `ReactiveOAuth2AuthorizedClientProvider` composite that provides support for the `authorization_code`, `refresh_token`, `client_credentials` and `password` authorization grant types:
+The following code shows an example of how to configure and build a `ReactiveOAuth2AuthorizedClientProvider` composite that provides support for the `authorization_code`, `refresh_token` and `client_credentials` authorization grant types:
 
 [tabs]
 ======
@@ -273,7 +273,6 @@ public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
 					.authorizationCode()
 					.refreshToken()
 					.clientCredentials()
-					.password()
 					.build();
 
 	DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager =
@@ -297,7 +296,6 @@ fun authorizedClientManager(
             .authorizationCode()
             .refreshToken()
             .clientCredentials()
-            .password()
             .build()
     val authorizedClientManager = DefaultReactiveOAuth2AuthorizedClientManager(
             clientRegistrationRepository, authorizedClientRepository)
@@ -312,7 +310,7 @@ In the case of a re-authorization failure, eg. a refresh token is no longer vali
 The default behaviour may be customized via `setAuthorizationSuccessHandler(ReactiveOAuth2AuthorizationSuccessHandler)` and `setAuthorizationFailureHandler(ReactiveOAuth2AuthorizationFailureHandler)`.
 
 The `DefaultReactiveOAuth2AuthorizedClientManager` is also associated with a `contextAttributesMapper` of type `Function<OAuth2AuthorizeRequest, Mono<Map<String, Object>>>`, which is responsible for mapping attribute(s) from the `OAuth2AuthorizeRequest` to a `Map` of attributes to be associated to the `OAuth2AuthorizationContext`.
-This can be useful when you need to supply a `ReactiveOAuth2AuthorizedClientProvider` with required (supported) attribute(s), eg. the `PasswordReactiveOAuth2AuthorizedClientProvider` requires the resource owner's `username` and `password` to be available in `OAuth2AuthorizationContext.getAttributes()`.
+This can be useful when you need to supply a `ReactiveOAuth2AuthorizedClientProvider` with required (supported) attribute(s).
 
 The following code shows an example of the `contextAttributesMapper`:
 
@@ -329,7 +327,7 @@ public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
 
 	ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
 			ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
-					.password()
+					.authorizationCode()
 					.refreshToken()
 					.build();
 
@@ -338,7 +336,7 @@ public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
 					clientRegistrationRepository, authorizedClientRepository);
 	authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 
-	// Assuming the `username` and `password` are supplied as `ServerHttpRequest` parameters,
+	// Assuming the attributes are supplied as `ServerHttpRequest` parameters,
 	// map the `ServerHttpRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
 	authorizedClientManager.setContextAttributesMapper(contextAttributesMapper());
 
@@ -350,14 +348,12 @@ private Function<OAuth2AuthorizeRequest, Mono<Map<String, Object>>> contextAttri
 		Map<String, Object> contextAttributes = Collections.emptyMap();
 		ServerWebExchange exchange = authorizeRequest.getAttribute(ServerWebExchange.class.getName());
 		ServerHttpRequest request = exchange.getRequest();
-		String username = request.getQueryParams().getFirst(OAuth2ParameterNames.USERNAME);
-		String password = request.getQueryParams().getFirst(OAuth2ParameterNames.PASSWORD);
-		if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
+		String param1 = request.getQueryParams().getFirst("param1");
+		String param2 = request.getQueryParams().getFirst("param2");
+		if (StringUtils.hasText(param1) && StringUtils.hasText(param2)) {
 			contextAttributes = new HashMap<>();
-
-			// `PasswordReactiveOAuth2AuthorizedClientProvider` requires both attributes
-			contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-			contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
+			contextAttributes.put("param1", param1);
+			contextAttributes.put("param2", param2);
 		}
 		return Mono.just(contextAttributes);
 	};
@@ -373,15 +369,15 @@ fun authorizedClientManager(
         clientRegistrationRepository: ReactiveClientRegistrationRepository,
         authorizedClientRepository: ServerOAuth2AuthorizedClientRepository): ReactiveOAuth2AuthorizedClientManager {
     val authorizedClientProvider: ReactiveOAuth2AuthorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
-            .password()
+            .authorizationCode()
             .refreshToken()
             .build()
     val authorizedClientManager = DefaultReactiveOAuth2AuthorizedClientManager(
             clientRegistrationRepository, authorizedClientRepository)
     authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
 
-    // Assuming the `username` and `password` are supplied as `ServerHttpRequest` parameters,
-    // map the `ServerHttpRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
+	// Assuming the attributes are supplied as `ServerHttpRequest` parameters,
+	// map the `ServerHttpRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
     authorizedClientManager.setContextAttributesMapper(contextAttributesMapper())
     return authorizedClientManager
 }
@@ -391,14 +387,12 @@ private fun contextAttributesMapper(): Function<OAuth2AuthorizeRequest, Mono<Mut
         var contextAttributes: MutableMap<String, Any> = mutableMapOf()
         val exchange: ServerWebExchange = authorizeRequest.getAttribute(ServerWebExchange::class.java.name)!!
         val request: ServerHttpRequest = exchange.request
-        val username: String? = request.queryParams.getFirst(OAuth2ParameterNames.USERNAME)
-        val password: String? = request.queryParams.getFirst(OAuth2ParameterNames.PASSWORD)
-        if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
+        val param1: String? = request.queryParams.getFirst("param1")
+        val param2: String? = request.queryParams.getFirst("param2")
+        if (StringUtils.hasText(param1) && StringUtils.hasText(param2)) {
             contextAttributes = hashMapOf()
-
-            // `PasswordReactiveOAuth2AuthorizedClientProvider` requires both attributes
-            contextAttributes[OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME] = username!!
-            contextAttributes[OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME] = password!!
+            contextAttributes["param1"] = param1!!
+            contextAttributes["param2"] = param2!!
         }
         Mono.just(contextAttributes)
     }

+ 1 - 4
docs/modules/ROOT/pages/reactive/oauth2/client/index.adoc

@@ -10,7 +10,6 @@ At a high-level, the core features available are:
 * xref:reactive/oauth2/client/authorization-grants.adoc#oauth2-client-authorization-code[Authorization Code]
 * xref:reactive/oauth2/client/authorization-grants.adoc#oauth2-client-refresh-token[Refresh Token]
 * xref:reactive/oauth2/client/authorization-grants.adoc#oauth2-client-client-credentials[Client Credentials]
-* xref:reactive/oauth2/client/authorization-grants.adoc#oauth2-client-password[Resource Owner Password Credentials]
 * xref:reactive/oauth2/client/authorization-grants.adoc#oauth2-client-jwt-bearer[JWT Bearer]
 * xref:reactive/oauth2/client/authorization-grants.adoc#oauth2-client-token-exchange[Token Exchange]
 
@@ -81,7 +80,7 @@ class OAuth2ClientSecurityConfig {
 
 The `ReactiveOAuth2AuthorizedClientManager` is responsible for managing the authorization (or re-authorization) of an OAuth 2.0 Client, in collaboration with one or more `ReactiveOAuth2AuthorizedClientProvider`(s).
 
-The following code shows an example of how to register a `ReactiveOAuth2AuthorizedClientManager` `@Bean` and associate it with a `ReactiveOAuth2AuthorizedClientProvider` composite that provides support for the `authorization_code`, `refresh_token`, `client_credentials` and `password` authorization grant types:
+The following code shows an example of how to register a `ReactiveOAuth2AuthorizedClientManager` `@Bean` and associate it with a `ReactiveOAuth2AuthorizedClientProvider` composite that provides support for the `authorization_code`, `refresh_token` and `client_credentials` authorization grant types:
 
 [tabs]
 ======
@@ -99,7 +98,6 @@ public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
 					.authorizationCode()
 					.refreshToken()
 					.clientCredentials()
-					.password()
 					.build();
 
 	DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager =
@@ -123,7 +121,6 @@ fun authorizedClientManager(
             .authorizationCode()
             .refreshToken()
             .clientCredentials()
-            .password()
             .build()
     val authorizedClientManager = DefaultReactiveOAuth2AuthorizedClientManager(
             clientRegistrationRepository, authorizedClientRepository)

+ 0 - 33
docs/modules/ROOT/pages/reactive/oauth2/index.adoc

@@ -953,7 +953,6 @@ public class SecurityConfig {
 				.authorizationCode()
 				.refreshToken()
 				.clientCredentials()
-				.password()
 				.provider(new JwtBearerReactiveOAuth2AuthorizedClientProvider())
 				.build();
 
@@ -984,7 +983,6 @@ class SecurityConfig {
 			.authorizationCode()
 			.refreshToken()
 			.clientCredentials()
-			.password()
 			.provider(JwtBearerReactiveOAuth2AuthorizedClientProvider())
 			.build()
 
@@ -1273,7 +1271,6 @@ Spring Security automatically resolves the following generic types of `ReactiveO
 * `OAuth2AuthorizationCodeGrantRequest` (see `WebClientReactiveAuthorizationCodeTokenResponseClient`)
 * `OAuth2RefreshTokenGrantRequest` (see `WebClientReactiveRefreshTokenTokenResponseClient`)
 * `OAuth2ClientCredentialsGrantRequest` (see `WebClientReactiveClientCredentialsTokenResponseClient`)
-* `OAuth2PasswordGrantRequest` (see `WebClientReactivePasswordTokenResponseClient`)
 * `JwtBearerGrantRequest` (see `WebClientReactiveJwtBearerTokenResponseClient`)
 * `TokenExchangeGrantRequest` (see `WebClientReactiveTokenExchangeTokenResponseClient`)
 
@@ -1334,15 +1331,6 @@ public class SecurityConfig {
 		return accessTokenResponseClient;
 	}
 
-	@Bean
-	public ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> passwordAccessTokenResponseClient() {
-		WebClientReactivePasswordTokenResponseClient accessTokenResponseClient =
-			new WebClientReactivePasswordTokenResponseClient();
-		accessTokenResponseClient.setWebClient(webClient());
-
-		return accessTokenResponseClient;
-	}
-
 	@Bean
 	public ReactiveOAuth2AccessTokenResponseClient<JwtBearerGrantRequest> jwtBearerAccessTokenResponseClient() {
 		WebClientReactiveJwtBearerTokenResponseClient accessTokenResponseClient =
@@ -1400,14 +1388,6 @@ class SecurityConfig {
 		return accessTokenResponseClient
 	}
 
-	@Bean
-	fun passwordAccessTokenResponseClient(): ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> {
-		val accessTokenResponseClient = WebClientReactivePasswordTokenResponseClient()
-		accessTokenResponseClient.setWebClient(webClient())
-
-		return accessTokenResponseClient
-	}
-
 	@Bean
 	fun jwtBearerAccessTokenResponseClient(): ReactiveOAuth2AccessTokenResponseClient<JwtBearerGrantRequest> {
 		val accessTokenResponseClient = WebClientReactiveJwtBearerTokenResponseClient()
@@ -1477,10 +1457,6 @@ public class SecurityConfig {
 			new WebClientReactiveClientCredentialsTokenResponseClient();
 		clientCredentialsAccessTokenResponseClient.setWebClient(webClient());
 
-		WebClientReactivePasswordTokenResponseClient passwordAccessTokenResponseClient =
-			new WebClientReactivePasswordTokenResponseClient();
-		passwordAccessTokenResponseClient.setWebClient(webClient());
-
 		WebClientReactiveJwtBearerTokenResponseClient jwtBearerAccessTokenResponseClient =
 			new WebClientReactiveJwtBearerTokenResponseClient();
 		jwtBearerAccessTokenResponseClient.setWebClient(webClient());
@@ -1506,9 +1482,6 @@ public class SecurityConfig {
 				.clientCredentials((clientCredentials) -> clientCredentials
 					.accessTokenResponseClient(clientCredentialsAccessTokenResponseClient)
 				)
-				.password((password) -> password
-					.accessTokenResponseClient(passwordAccessTokenResponseClient)
-				)
 				.provider(jwtBearerAuthorizedClientProvider)
 				.provider(tokenExchangeAuthorizedClientProvider)
 				.build();
@@ -1557,9 +1530,6 @@ class SecurityConfig {
 		val clientCredentialsAccessTokenResponseClient = WebClientReactiveClientCredentialsTokenResponseClient()
 		clientCredentialsAccessTokenResponseClient.setWebClient(webClient())
 
-		val passwordAccessTokenResponseClient = WebClientReactivePasswordTokenResponseClient()
-		passwordAccessTokenResponseClient.setWebClient(webClient())
-
 		val jwtBearerAccessTokenResponseClient = WebClientReactiveJwtBearerTokenResponseClient()
 		jwtBearerAccessTokenResponseClient.setWebClient(webClient())
 
@@ -1580,9 +1550,6 @@ class SecurityConfig {
 			.clientCredentials { clientCredentials ->
 				clientCredentials.accessTokenResponseClient(clientCredentialsAccessTokenResponseClient)
 			}
-			.password { password ->
-				password.accessTokenResponseClient(passwordAccessTokenResponseClient)
-			}
 			.provider(jwtBearerAuthorizedClientProvider)
 			.provider(tokenExchangeAuthorizedClientProvider)
 			.build()

+ 2 - 324
docs/modules/ROOT/pages/servlet/oauth2/client/authorization-grants.adoc

@@ -546,7 +546,7 @@ authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
 which is an implementation of an `OAuth2AuthorizedClientProvider` for the Refresh Token grant.
 ====
 
-The `OAuth2RefreshToken` can optionally be returned in the Access Token Response for the `authorization_code` and `password` grant types.
+The `OAuth2RefreshToken` can optionally be returned in the Access Token Response for the `authorization_code` grant type.
 If the `OAuth2AuthorizedClient.getRefreshToken()` is available and the `OAuth2AuthorizedClient.getAccessToken()` is expired, it is automatically refreshed by the `RefreshTokenOAuth2AuthorizedClientProvider`.
 
 [[oauth2-client-client-credentials]]
@@ -778,330 +778,8 @@ class OAuth2ClientController {
 If not provided, they default to `ServletRequestAttributes` by using `RequestContextHolder.getRequestAttributes()`.
 ====
 
-[[oauth2-client-password]]
-== [[oauth2Client-password-grant]]Resource Owner Password Credentials
-
-[NOTE]
-====
-See the OAuth 2.0 Authorization Framework for further details on the https://tools.ietf.org/html/rfc6749#section-1.3.3[Resource Owner Password Credentials] grant.
-====
-
-[[oauth2-client-password-access-token]]
-=== Requesting an Access Token
-
-[NOTE]
-====
-See the https://tools.ietf.org/html/rfc6749#section-4.3.2[Access Token Request/Response] protocol flow for the Resource Owner Password Credentials grant.
-====
-
-The default implementation of `OAuth2AccessTokenResponseClient` for the Resource Owner Password Credentials grant is `DefaultPasswordTokenResponseClient`, which uses a `RestOperations` when requesting an access token at the Authorization Server’s Token Endpoint.
-
-[CAUTION]
-====
-The `DefaultPasswordTokenResponseClient` class and support for the Resource Owner Password Credentials grant are deprecated.
-This section will be removed in Spring Security 7.
-====
-
-The `DefaultPasswordTokenResponseClient` is flexible, as it lets you customize the pre-processing of the Token Request or post-handling of the Token Response.
-
-[[oauth2-client-password-access-token-request]]
-=== Customizing the Access Token Request
-
-If you need to customize the pre-processing of the Token Request, you can provide `DefaultPasswordTokenResponseClient.setRequestEntityConverter()` with a custom `Converter<OAuth2PasswordGrantRequest, RequestEntity<?>>`.
-The default implementation (`OAuth2PasswordGrantRequestEntityConverter`) builds a `RequestEntity` representation of a standard https://tools.ietf.org/html/rfc6749#section-4.3.2[OAuth 2.0 Access Token Request].
-However, providing a custom `Converter` would let you extend the standard Token Request and add custom parameter(s).
-
-To customize only the parameters of the request, you can provide `OAuth2PasswordGrantRequestEntityConverter.setParametersConverter()` with a custom `Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>>` to completely override the parameters sent with the request. This is often simpler than constructing a `RequestEntity` directly.
-
-[TIP]
-====
-If you prefer to only add additional parameters, you can provide `OAuth2PasswordGrantRequestEntityConverter.addParametersConverter()` with a custom `Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>>` which constructs an aggregate `Converter`.
-====
-
-[IMPORTANT]
-====
-The custom `Converter` must return a valid `RequestEntity` representation of an OAuth 2.0 Access Token Request that is understood by the intended OAuth 2.0 Provider.
-====
-
-[[oauth2-client-password-access-token-response]]
-=== Customizing the Access Token Response
-
-On the other end, if you need to customize the post-handling of the Token Response, you need to provide `DefaultPasswordTokenResponseClient.setRestOperations()` with a custom configured `RestOperations`.
-The default `RestOperations` is configured as follows:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-RestTemplate restTemplate = new RestTemplate(Arrays.asList(
-		new FormHttpMessageConverter(),
-		new OAuth2AccessTokenResponseHttpMessageConverter()));
-
-restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val restTemplate = RestTemplate(listOf(
-        FormHttpMessageConverter(),
-        OAuth2AccessTokenResponseHttpMessageConverter()))
-
-restTemplate.errorHandler = OAuth2ErrorResponseErrorHandler()
-----
-======
-
-[TIP]
-====
-Spring MVC `FormHttpMessageConverter` is required, as it is used when sending the OAuth 2.0 Access Token Request.
-====
-
-`OAuth2AccessTokenResponseHttpMessageConverter` is a `HttpMessageConverter` for an OAuth 2.0 Access Token Response.
-You can provide `OAuth2AccessTokenResponseHttpMessageConverter.setTokenResponseConverter()` with a custom `Converter<Map<String, String>, OAuth2AccessTokenResponse>` that is used to convert the OAuth 2.0 Access Token Response parameters to an `OAuth2AccessTokenResponse`.
-
-`OAuth2ErrorResponseErrorHandler` is a `ResponseErrorHandler` that can handle an OAuth 2.0 Error, such as `400 Bad Request`.
-It uses an `OAuth2ErrorHttpMessageConverter` to convert the OAuth 2.0 Error parameters to an `OAuth2Error`.
-
-[[oauth2-client-password-authorized-client-provider-builder]]
-=== Customize using the Builder
-
-Whether you customize `DefaultPasswordTokenResponseClient` or provide your own implementation of `OAuth2AccessTokenResponseClient`, you need to configure it as follows:
-
-.Access Token Response Configuration via Builder
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-// Customize
-OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> passwordTokenResponseClient = ...
-
-OAuth2AuthorizedClientProvider authorizedClientProvider =
-		OAuth2AuthorizedClientProviderBuilder.builder()
-				.password((configurer) -> configurer.accessTokenResponseClient(passwordTokenResponseClient))
-				.refreshToken()
-				.build();
-
-// ...
-
-authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-val passwordTokenResponseClient: OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> = ...
-
-val authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
-        .password { it.accessTokenResponseClient(passwordTokenResponseClient) }
-        .refreshToken()
-        .build()
-
-// ...
-
-authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
-----
-======
-
-[NOTE]
-====
-`OAuth2AuthorizedClientProviderBuilder.builder().password()` configures a `PasswordOAuth2AuthorizedClientProvider`,
-which is an implementation of an `OAuth2AuthorizedClientProvider` for the Resource Owner Password Credentials grant.
-====
-
-[[oauth2-client-password-authorized-client-manager]]
-=== Using the Access Token
-
-Consider the following Spring Boot properties for an OAuth 2.0 Client registration:
-
-[source,yaml]
-----
-spring:
-  security:
-    oauth2:
-      client:
-        registration:
-          okta:
-            client-id: okta-client-id
-            client-secret: okta-client-secret
-            authorization-grant-type: password
-            scope: read, write
-        provider:
-          okta:
-            token-uri: https://dev-1234.oktapreview.com/oauth2/v1/token
-----
-
-Further consider the `OAuth2AuthorizedClientManager` `@Bean`:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Bean
-public OAuth2AuthorizedClientManager authorizedClientManager(
-		ClientRegistrationRepository clientRegistrationRepository,
-		OAuth2AuthorizedClientRepository authorizedClientRepository) {
-
-	OAuth2AuthorizedClientProvider authorizedClientProvider =
-			OAuth2AuthorizedClientProviderBuilder.builder()
-					.password()
-					.refreshToken()
-					.build();
-
-	DefaultOAuth2AuthorizedClientManager authorizedClientManager =
-			new DefaultOAuth2AuthorizedClientManager(
-					clientRegistrationRepository, authorizedClientRepository);
-	authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
-
-	// Assuming the `username` and `password` are supplied as `HttpServletRequest` parameters,
-	// map the `HttpServletRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
-	authorizedClientManager.setContextAttributesMapper(contextAttributesMapper());
-
-	return authorizedClientManager;
-}
-
-private Function<OAuth2AuthorizeRequest, Map<String, Object>> contextAttributesMapper() {
-	return authorizeRequest -> {
-		Map<String, Object> contextAttributes = Collections.emptyMap();
-		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)) {
-			contextAttributes = new HashMap<>();
-
-			// `PasswordOAuth2AuthorizedClientProvider` requires both attributes
-			contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-			contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
-		}
-		return contextAttributes;
-	};
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Bean
-fun authorizedClientManager(
-        clientRegistrationRepository: ClientRegistrationRepository,
-        authorizedClientRepository: OAuth2AuthorizedClientRepository): OAuth2AuthorizedClientManager {
-    val authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
-            .password()
-            .refreshToken()
-            .build()
-    val authorizedClientManager = DefaultOAuth2AuthorizedClientManager(
-            clientRegistrationRepository, authorizedClientRepository)
-    authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
-
-    // Assuming the `username` and `password` are supplied as `HttpServletRequest` parameters,
-    // map the `HttpServletRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
-    authorizedClientManager.setContextAttributesMapper(contextAttributesMapper())
-    return authorizedClientManager
-}
-
-private fun contextAttributesMapper(): Function<OAuth2AuthorizeRequest, MutableMap<String, Any>> {
-    return Function { authorizeRequest ->
-        var contextAttributes: MutableMap<String, Any> = mutableMapOf()
-        val servletRequest: HttpServletRequest = authorizeRequest.getAttribute(HttpServletRequest::class.java.name)
-        val username = servletRequest.getParameter(OAuth2ParameterNames.USERNAME)
-        val password = servletRequest.getParameter(OAuth2ParameterNames.PASSWORD)
-        if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
-            contextAttributes = hashMapOf()
-
-            // `PasswordOAuth2AuthorizedClientProvider` requires both attributes
-            contextAttributes[OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME] = username
-            contextAttributes[OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME] = password
-        }
-        contextAttributes
-    }
-}
-----
-======
-
-Given the preceding properties and bean, you can obtain the `OAuth2AccessToken` as follows:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Controller
-public class OAuth2ClientController {
-
-	@Autowired
-	private OAuth2AuthorizedClientManager authorizedClientManager;
-
-	@GetMapping("/")
-	public String index(Authentication authentication,
-						HttpServletRequest servletRequest,
-						HttpServletResponse servletResponse) {
-
-		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("okta")
-				.principal(authentication)
-				.attributes(attrs -> {
-					attrs.put(HttpServletRequest.class.getName(), servletRequest);
-					attrs.put(HttpServletResponse.class.getName(), servletResponse);
-				})
-				.build();
-		OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
-
-		OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
-
-		// ...
-
-		return "index";
-	}
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Controller
-class OAuth2ClientController {
-    @Autowired
-    private lateinit var authorizedClientManager: OAuth2AuthorizedClientManager
-
-    @GetMapping("/")
-    fun index(authentication: Authentication?,
-              servletRequest: HttpServletRequest,
-              servletResponse: HttpServletResponse): String {
-        val authorizeRequest: OAuth2AuthorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("okta")
-                .principal(authentication)
-                .attributes(Consumer {
-                    it[HttpServletRequest::class.java.name] = servletRequest
-                    it[HttpServletResponse::class.java.name] = servletResponse
-                })
-                .build()
-        val authorizedClient = authorizedClientManager.authorize(authorizeRequest)
-        val accessToken: OAuth2AccessToken = authorizedClient.accessToken
-
-        // ...
-
-        return "index"
-    }
-}
-----
-======
-
-[NOTE]
-====
-`HttpServletRequest` and `HttpServletResponse` are both OPTIONAL attributes.
-If not provided, they default to `ServletRequestAttributes` using `RequestContextHolder.getRequestAttributes()`.
-====
-
 [[oauth2-client-jwt-bearer]]
-== [[oauth2Client-jwt-bearer-grant]]JWT Bearer
+== JWT Bearer
 
 [NOTE]
 ====

+ 0 - 2
docs/modules/ROOT/pages/servlet/oauth2/client/authorized-clients.adoc

@@ -60,7 +60,6 @@ The interceptor directly uses an `OAuth2AuthorizedClientManager` and therefore i
 * Performs an OAuth 2.0 Access Token request to obtain `OAuth2AccessToken` if the client has not yet been authorized
 ** `authorization_code`: Triggers the Authorization Request redirect to initiate the flow
 ** `client_credentials`: The access token is obtained directly from the Token Endpoint
-** `password`: The access token is obtained directly from the Token Endpoint
 ** Additional grant types are supported by xref:servlet/oauth2/index.adoc#oauth2-client-enable-extension-grant-type[enabling extension grant types]
 * If an existing `OAuth2AccessToken` is expired, it is refreshed (or renewed)
 
@@ -511,7 +510,6 @@ It directly uses an xref:servlet/oauth2/client/core.adoc#oauth2Client-authorized
 * An `OAuth2AccessToken` is requested if the client has not yet been authorized.
 ** `authorization_code`: Triggers the Authorization Request redirect to initiate the flow.
 ** `client_credentials`: The access token is obtained directly from the Token Endpoint.
-** `password`: The access token is obtained directly from the Token Endpoint.
 * If the `OAuth2AccessToken` is expired, it is refreshed (or renewed) if an `OAuth2AuthorizedClientProvider` is available to perform the authorization
 
 The following code shows an example of how to configure `WebClient` with OAuth 2.0 Client support:

+ 18 - 24
docs/modules/ROOT/pages/servlet/oauth2/client/core.adoc

@@ -52,7 +52,7 @@ public final class ClientRegistration {
 <4> `clientAuthenticationMethod`: The method used to authenticate the Client with the Provider.
 The supported values are *client_secret_basic*, *client_secret_post*, *private_key_jwt*, *client_secret_jwt* and *none* https://tools.ietf.org/html/rfc6749#section-2.1[(public clients)].
 <5> `authorizationGrantType`: The OAuth 2.0 Authorization Framework defines four https://tools.ietf.org/html/rfc6749#section-1.3[Authorization Grant] types.
- The supported values are `authorization_code`, `client_credentials`, `password`, as well as, extension grant type `urn:ietf:params:oauth:grant-type:jwt-bearer`.
+ The supported values are `authorization_code`, `client_credentials`, as well as, extension grant type `urn:ietf:params:oauth:grant-type:jwt-bearer`.
 <6> `redirectUri`: The client's registered redirect URI that the _Authorization Server_ redirects the end-user's user-agent
  to after the end-user has authenticated and authorized access to the client.
 <7> `scopes`: The scope(s) requested by the client during the Authorization Request flow, such as openid, email, or profile.
@@ -268,7 +268,7 @@ Implementations typically implement an authorization grant type, such as `author
 The default implementation of `OAuth2AuthorizedClientManager` is `DefaultOAuth2AuthorizedClientManager`, which is associated with an `OAuth2AuthorizedClientProvider` that may support multiple authorization grant types using a delegation-based composite.
 You can use `OAuth2AuthorizedClientProviderBuilder` to configure and build the delegation-based composite.
 
-The following code shows an example of how to configure and build an `OAuth2AuthorizedClientProvider` composite that provides support for the `authorization_code`, `refresh_token`, `client_credentials`, and `password` authorization grant types:
+The following code shows an example of how to configure and build an `OAuth2AuthorizedClientProvider` composite that provides support for the `authorization_code`, `refresh_token` and `client_credentials` authorization grant types:
 
 [tabs]
 ======
@@ -286,7 +286,6 @@ public OAuth2AuthorizedClientManager authorizedClientManager(
 					.authorizationCode()
 					.refreshToken()
 					.clientCredentials()
-					.password()
 					.build();
 
 	DefaultOAuth2AuthorizedClientManager authorizedClientManager =
@@ -310,7 +309,6 @@ fun authorizedClientManager(
             .authorizationCode()
             .refreshToken()
             .clientCredentials()
-            .password()
             .build()
     val authorizedClientManager = DefaultOAuth2AuthorizedClientManager(
             clientRegistrationRepository, authorizedClientRepository)
@@ -325,7 +323,7 @@ In the case of a re-authorization failure (for example, a refresh token is no lo
 You can customize the default behavior through `setAuthorizationSuccessHandler(OAuth2AuthorizationSuccessHandler)` and `setAuthorizationFailureHandler(OAuth2AuthorizationFailureHandler)`.
 
 The `DefaultOAuth2AuthorizedClientManager` is also associated with a `contextAttributesMapper` of type `Function<OAuth2AuthorizeRequest, Map<String, Object>>`, which is responsible for mapping attribute(s) from the `OAuth2AuthorizeRequest` to a `Map` of attributes to be associated to the `OAuth2AuthorizationContext`.
-This can be useful when you need to supply an `OAuth2AuthorizedClientProvider` with required (supported) attribute(s), eg. the `PasswordOAuth2AuthorizedClientProvider` requires the resource owner's `username` and `password` to be available in `OAuth2AuthorizationContext.getAttributes()`.
+This can be useful when you need to supply an `OAuth2AuthorizedClientProvider` with required (supported) attribute(s).
 
 The following code shows an example of the `contextAttributesMapper`:
 
@@ -342,7 +340,7 @@ public OAuth2AuthorizedClientManager authorizedClientManager(
 
 	OAuth2AuthorizedClientProvider authorizedClientProvider =
 			OAuth2AuthorizedClientProviderBuilder.builder()
-					.password()
+					.authorizationCode()
 					.refreshToken()
 					.build();
 
@@ -351,7 +349,7 @@ public OAuth2AuthorizedClientManager authorizedClientManager(
 					clientRegistrationRepository, authorizedClientRepository);
 	authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
 
-	// Assuming the `username` and `password` are supplied as `HttpServletRequest` parameters,
+	// Assuming the attributes are supplied as `HttpServletRequest` parameters,
 	// map the `HttpServletRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
 	authorizedClientManager.setContextAttributesMapper(contextAttributesMapper());
 
@@ -362,14 +360,12 @@ private Function<OAuth2AuthorizeRequest, Map<String, Object>> contextAttributesM
 	return authorizeRequest -> {
 		Map<String, Object> contextAttributes = Collections.emptyMap();
 		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)) {
+		String param1 = servletRequest.getParameter("param1");
+		String param2 = servletRequest.getParameter("param2");
+		if (StringUtils.hasText(param1) && StringUtils.hasText(param2)) {
 			contextAttributes = new HashMap<>();
-
-			// `PasswordOAuth2AuthorizedClientProvider` requires both attributes
-			contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-			contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
+			contextAttributes.put("param1", param1);
+			contextAttributes.put("param2", param2);
 		}
 		return contextAttributes;
 	};
@@ -385,15 +381,15 @@ fun authorizedClientManager(
         clientRegistrationRepository: ClientRegistrationRepository,
         authorizedClientRepository: OAuth2AuthorizedClientRepository): OAuth2AuthorizedClientManager {
     val authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
-            .password()
+            .authorizationCode()
             .refreshToken()
             .build()
     val authorizedClientManager = DefaultOAuth2AuthorizedClientManager(
             clientRegistrationRepository, authorizedClientRepository)
     authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider)
 
-    // Assuming the `username` and `password` are supplied as `HttpServletRequest` parameters,
-    // map the `HttpServletRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
+	// Assuming the attributes are supplied as `HttpServletRequest` parameters,
+	// map the `HttpServletRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
     authorizedClientManager.setContextAttributesMapper(contextAttributesMapper())
     return authorizedClientManager
 }
@@ -402,14 +398,12 @@ private fun contextAttributesMapper(): Function<OAuth2AuthorizeRequest, MutableM
     return Function { authorizeRequest ->
         var contextAttributes: MutableMap<String, Any> = mutableMapOf()
         val servletRequest: HttpServletRequest = authorizeRequest.getAttribute(HttpServletRequest::class.java.name)
-        val username: String = servletRequest.getParameter(OAuth2ParameterNames.USERNAME)
-        val password: String = servletRequest.getParameter(OAuth2ParameterNames.PASSWORD)
-        if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
+        val param1: String = servletRequest.getParameter("param1")
+        val param2: String = servletRequest.getParameter("param2")
+        if (StringUtils.hasText(param1) && StringUtils.hasText(param2)) {
             contextAttributes = hashMapOf()
-
-            // `PasswordOAuth2AuthorizedClientProvider` requires both attributes
-            contextAttributes[OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME] = username
-            contextAttributes[OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME] = password
+            contextAttributes["param1"] = param1
+            contextAttributes["param2"] = param2
         }
         contextAttributes
     }

+ 1 - 4
docs/modules/ROOT/pages/servlet/oauth2/client/index.adoc

@@ -10,7 +10,6 @@ At a high-level, the core features available are:
 * xref:servlet/oauth2/client/authorization-grants.adoc#oauth2-client-authorization-code[Authorization Code]
 * xref:servlet/oauth2/client/authorization-grants.adoc#oauth2-client-refresh-token[Refresh Token]
 * xref:servlet/oauth2/client/authorization-grants.adoc#oauth2-client-client-credentials[Client Credentials]
-* xref:servlet/oauth2/client/authorization-grants.adoc#oauth2-client-password[Resource Owner Password Credentials]
 * xref:servlet/oauth2/client/authorization-grants.adoc#oauth2-client-jwt-bearer[JWT Bearer]
 * xref:servlet/oauth2/client/authorization-grants.adoc#oauth2-client-token-exchange[Token Exchange]
 
@@ -104,7 +103,7 @@ The following code shows the complete configuration options available in the xre
 
 The `OAuth2AuthorizedClientManager` is responsible for managing the authorization (or re-authorization) of an OAuth 2.0 Client, in collaboration with one or more `OAuth2AuthorizedClientProvider`(s).
 
-The following code shows an example of how to register an `OAuth2AuthorizedClientManager` `@Bean` and associate it with an `OAuth2AuthorizedClientProvider` composite that provides support for the `authorization_code`, `refresh_token`, `client_credentials`, and `password` authorization grant types:
+The following code shows an example of how to register an `OAuth2AuthorizedClientManager` `@Bean` and associate it with an `OAuth2AuthorizedClientProvider` composite that provides support for the `authorization_code`, `refresh_token` and `client_credentials` authorization grant types:
 
 [tabs]
 ======
@@ -122,7 +121,6 @@ public OAuth2AuthorizedClientManager authorizedClientManager(
 					.authorizationCode()
 					.refreshToken()
 					.clientCredentials()
-					.password()
 					.build();
 
 	DefaultOAuth2AuthorizedClientManager authorizedClientManager =
@@ -146,7 +144,6 @@ fun authorizedClientManager(
             .authorizationCode()
             .refreshToken()
             .clientCredentials()
-            .password()
             .build()
     val authorizedClientManager = DefaultOAuth2AuthorizedClientManager(
             clientRegistrationRepository, authorizedClientRepository)

+ 0 - 33
docs/modules/ROOT/pages/servlet/oauth2/index.adoc

@@ -1367,7 +1367,6 @@ public class SecurityConfig {
 				.authorizationCode()
 				.refreshToken()
 				.clientCredentials()
-				.password()
 				.provider(new JwtBearerOAuth2AuthorizedClientProvider())
 				.build();
 
@@ -1398,7 +1397,6 @@ class SecurityConfig {
 			.authorizationCode()
 			.refreshToken()
 			.clientCredentials()
-			.password()
 			.provider(JwtBearerOAuth2AuthorizedClientProvider())
 			.build()
 
@@ -1699,7 +1697,6 @@ Spring Security automatically resolves the following generic types of `OAuth2Acc
 * `OAuth2AuthorizationCodeGrantRequest` (see `DefaultAuthorizationCodeTokenResponseClient`)
 * `OAuth2RefreshTokenGrantRequest` (see `DefaultRefreshTokenTokenResponseClient`)
 * `OAuth2ClientCredentialsGrantRequest` (see `DefaultClientCredentialsTokenResponseClient`)
-* `OAuth2PasswordGrantRequest` (see `DefaultPasswordTokenResponseClient`)
 * `JwtBearerGrantRequest` (see `DefaultJwtBearerTokenResponseClient`)
 * `TokenExchangeGrantRequest` (see `DefaultTokenExchangeTokenResponseClient`)
 
@@ -1760,15 +1757,6 @@ public class SecurityConfig {
 		return accessTokenResponseClient;
 	}
 
-	@Bean
-	public OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> passwordAccessTokenResponseClient() {
-		DefaultPasswordTokenResponseClient accessTokenResponseClient =
-			new DefaultPasswordTokenResponseClient();
-		accessTokenResponseClient.setRestOperations(restTemplate());
-
-		return accessTokenResponseClient;
-	}
-
 	@Bean
 	public OAuth2AccessTokenResponseClient<JwtBearerGrantRequest> jwtBearerAccessTokenResponseClient() {
 		DefaultJwtBearerTokenResponseClient accessTokenResponseClient =
@@ -1826,14 +1814,6 @@ class SecurityConfig {
 		return accessTokenResponseClient
 	}
 
-	@Bean
-	fun passwordAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> {
-		val accessTokenResponseClient = DefaultPasswordTokenResponseClient()
-		accessTokenResponseClient.setRestOperations(restTemplate())
-
-		return accessTokenResponseClient
-	}
-
 	@Bean
 	fun jwtBearerAccessTokenResponseClient(): OAuth2AccessTokenResponseClient<JwtBearerGrantRequest> {
 		val accessTokenResponseClient = DefaultJwtBearerTokenResponseClient()
@@ -1917,10 +1897,6 @@ public class SecurityConfig {
 			new DefaultClientCredentialsTokenResponseClient();
 		clientCredentialsAccessTokenResponseClient.setRestOperations(restTemplate());
 
-		DefaultPasswordTokenResponseClient passwordAccessTokenResponseClient =
-			new DefaultPasswordTokenResponseClient();
-		passwordAccessTokenResponseClient.setRestOperations(restTemplate());
-
 		DefaultJwtBearerTokenResponseClient jwtBearerAccessTokenResponseClient =
 			new DefaultJwtBearerTokenResponseClient();
 		jwtBearerAccessTokenResponseClient.setRestOperations(restTemplate());
@@ -1946,9 +1922,6 @@ public class SecurityConfig {
 				.clientCredentials((clientCredentials) -> clientCredentials
 					.accessTokenResponseClient(clientCredentialsAccessTokenResponseClient)
 				)
-				.password((password) -> password
-					.accessTokenResponseClient(passwordAccessTokenResponseClient)
-				)
 				.provider(jwtBearerAuthorizedClientProvider)
 				.provider(tokenExchangeAuthorizedClientProvider)
 				.build();
@@ -2012,9 +1985,6 @@ class SecurityConfig {
 		val clientCredentialsAccessTokenResponseClient = DefaultClientCredentialsTokenResponseClient()
 		clientCredentialsAccessTokenResponseClient.setRestOperations(restTemplate())
 
-		val passwordAccessTokenResponseClient = DefaultPasswordTokenResponseClient()
-		passwordAccessTokenResponseClient.setRestOperations(restTemplate())
-
 		val jwtBearerAccessTokenResponseClient = DefaultJwtBearerTokenResponseClient()
 		jwtBearerAccessTokenResponseClient.setRestOperations(restTemplate())
 
@@ -2035,9 +2005,6 @@ class SecurityConfig {
 			.clientCredentials { clientCredentials ->
 				clientCredentials.accessTokenResponseClient(clientCredentialsAccessTokenResponseClient)
 			}
-			.password { password ->
-				password.accessTokenResponseClient(passwordAccessTokenResponseClient)
-			}
 			.provider(jwtBearerAuthorizedClientProvider)
 			.provider(tokenExchangeAuthorizedClientProvider)
 			.build()

+ 1 - 13
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/OAuth2AuthorizationContext.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -48,18 +48,6 @@ public final class OAuth2AuthorizationContext {
 	public static final String REQUEST_SCOPE_ATTRIBUTE_NAME = OAuth2AuthorizationContext.class.getName()
 		.concat(".REQUEST_SCOPE");
 
-	/**
-	 * The name of the {@link #getAttribute(String) attribute} in the context associated
-	 * to the value for the resource owner's username.
-	 */
-	public static final String USERNAME_ATTRIBUTE_NAME = OAuth2AuthorizationContext.class.getName().concat(".USERNAME");
-
-	/**
-	 * The name of the {@link #getAttribute(String) attribute} in the context associated
-	 * to the value for the resource owner's password.
-	 */
-	public static final String PASSWORD_ATTRIBUTE_NAME = OAuth2AuthorizationContext.class.getName().concat(".PASSWORD");
-
 	private ClientRegistration clientRegistration;
 
 	private OAuth2AuthorizedClient authorizedClient;

+ 4 - 111
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/OAuth2AuthorizedClientProviderBuilder.java

@@ -28,7 +28,6 @@ import java.util.function.Consumer;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
 import org.springframework.util.Assert;
 
@@ -36,10 +35,10 @@ import org.springframework.util.Assert;
  * A builder that builds a {@link DelegatingOAuth2AuthorizedClientProvider} composed of
  * one or more {@link OAuth2AuthorizedClientProvider}(s) that implement specific
  * authorization grants. The supported authorization grants are
- * {@link #authorizationCode() authorization_code}, {@link #refreshToken() refresh_token},
- * {@link #clientCredentials() client_credentials} and {@link #password() password}. In
- * addition to the standard authorization grants, an implementation of an extension grant
- * may be supplied via {@link #provider(OAuth2AuthorizedClientProvider)}.
+ * {@link #authorizationCode() authorization_code}, {@link #refreshToken() refresh_token}
+ * and {@link #clientCredentials() client_credentials}. In addition to the standard
+ * authorization grants, an implementation of an extension grant may be supplied via
+ * {@link #provider(OAuth2AuthorizedClientProvider)}.
  *
  * @author Joe Grandja
  * @since 5.2
@@ -47,7 +46,6 @@ import org.springframework.util.Assert;
  * @see AuthorizationCodeOAuth2AuthorizedClientProvider
  * @see RefreshTokenOAuth2AuthorizedClientProvider
  * @see ClientCredentialsOAuth2AuthorizedClientProvider
- * @see PasswordOAuth2AuthorizedClientProvider
  * @see DelegatingOAuth2AuthorizedClientProvider
  */
 public final class OAuth2AuthorizedClientProviderBuilder {
@@ -135,38 +133,6 @@ public final class OAuth2AuthorizedClientProviderBuilder {
 		return OAuth2AuthorizedClientProviderBuilder.this;
 	}
 
-	/**
-	 * Configures support for the {@code password} grant.
-	 * @return the {@link OAuth2AuthorizedClientProviderBuilder}
-	 * @deprecated The OAuth 2.0 Security Best Current Practice disallows the use of the
-	 * Resource Owner Password Credentials grant. See reference <a target="_blank" href=
-	 * "https://datatracker.ietf.org/doc/html/rfc9700#section-2.4">OAuth 2.0 Security Best
-	 * Current Practice.</a>
-	 */
-	@Deprecated(since = "5.8", forRemoval = true)
-	public OAuth2AuthorizedClientProviderBuilder password() {
-		this.builders.computeIfAbsent(PasswordOAuth2AuthorizedClientProvider.class, (k) -> new PasswordGrantBuilder());
-		return OAuth2AuthorizedClientProviderBuilder.this;
-	}
-
-	/**
-	 * Configures support for the {@code password} grant.
-	 * @param builderConsumer a {@code Consumer} of {@link PasswordGrantBuilder} used for
-	 * further configuration
-	 * @return the {@link OAuth2AuthorizedClientProviderBuilder}
-	 * @deprecated The OAuth 2.0 Security Best Current Practice disallows the use of the
-	 * Resource Owner Password Credentials grant. See reference <a target="_blank" href=
-	 * "https://datatracker.ietf.org/doc/html/rfc9700#section-2.4">OAuth 2.0 Security Best
-	 * Current Practice.</a>
-	 */
-	@Deprecated(since = "5.8", forRemoval = true)
-	public OAuth2AuthorizedClientProviderBuilder password(Consumer<PasswordGrantBuilder> builderConsumer) {
-		PasswordGrantBuilder builder = (PasswordGrantBuilder) this.builders
-			.computeIfAbsent(PasswordOAuth2AuthorizedClientProvider.class, (k) -> new PasswordGrantBuilder());
-		builderConsumer.accept(builder);
-		return OAuth2AuthorizedClientProviderBuilder.this;
-	}
-
 	/**
 	 * Builds an instance of {@link DelegatingOAuth2AuthorizedClientProvider} composed of
 	 * one or more {@link OAuth2AuthorizedClientProvider}(s).
@@ -186,79 +152,6 @@ public final class OAuth2AuthorizedClientProviderBuilder {
 
 	}
 
-	/**
-	 * A builder for the {@code password} grant.
-	 */
-	public final class PasswordGrantBuilder implements Builder {
-
-		private OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient;
-
-		private Duration clockSkew;
-
-		private Clock clock;
-
-		private PasswordGrantBuilder() {
-		}
-
-		/**
-		 * Sets the client used when requesting an access token credential at the Token
-		 * Endpoint.
-		 * @param accessTokenResponseClient the client used when requesting an access
-		 * token credential at the Token Endpoint
-		 * @return the {@link PasswordGrantBuilder}
-		 */
-		public PasswordGrantBuilder accessTokenResponseClient(
-				OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient) {
-			this.accessTokenResponseClient = accessTokenResponseClient;
-			return this;
-		}
-
-		/**
-		 * Sets the maximum acceptable clock skew, which is used when checking the access
-		 * token expiry. An access token is considered expired if
-		 * {@code OAuth2Token#getExpiresAt() - clockSkew} is before the current time
-		 * {@code clock#instant()}.
-		 * @param clockSkew the maximum acceptable clock skew
-		 * @return the {@link PasswordGrantBuilder}
-		 * @see PasswordOAuth2AuthorizedClientProvider#setClockSkew(Duration)
-		 */
-		public PasswordGrantBuilder clockSkew(Duration clockSkew) {
-			this.clockSkew = clockSkew;
-			return this;
-		}
-
-		/**
-		 * Sets the {@link Clock} used in {@link Instant#now(Clock)} when checking the
-		 * access token expiry.
-		 * @param clock the clock
-		 * @return the {@link PasswordGrantBuilder}
-		 */
-		public PasswordGrantBuilder clock(Clock clock) {
-			this.clock = clock;
-			return this;
-		}
-
-		/**
-		 * Builds an instance of {@link PasswordOAuth2AuthorizedClientProvider}.
-		 * @return the {@link PasswordOAuth2AuthorizedClientProvider}
-		 */
-		@Override
-		public OAuth2AuthorizedClientProvider build() {
-			PasswordOAuth2AuthorizedClientProvider authorizedClientProvider = new PasswordOAuth2AuthorizedClientProvider();
-			if (this.accessTokenResponseClient != null) {
-				authorizedClientProvider.setAccessTokenResponseClient(this.accessTokenResponseClient);
-			}
-			if (this.clockSkew != null) {
-				authorizedClientProvider.setClockSkew(this.clockSkew);
-			}
-			if (this.clock != null) {
-				authorizedClientProvider.setClock(this.clock);
-			}
-			return authorizedClientProvider;
-		}
-
-	}
-
 	/**
 	 * A builder for the {@code client_credentials} grant.
 	 */

+ 0 - 167
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordOAuth2AuthorizedClientProvider.java

@@ -1,167 +0,0 @@
-/*
- * Copyright 2002-2025 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 java.time.Clock;
-import java.time.Duration;
-import java.time.Instant;
-
-import org.springframework.lang.Nullable;
-import org.springframework.security.oauth2.client.endpoint.DefaultPasswordTokenResponseClient;
-import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.core.AuthorizationGrantType;
-import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
-import org.springframework.security.oauth2.core.OAuth2Token;
-import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-/**
- * An implementation of an {@link OAuth2AuthorizedClientProvider} for the
- * {@link AuthorizationGrantType#PASSWORD password} grant.
- *
- * @author Joe Grandja
- * @since 5.2
- * @see OAuth2AuthorizedClientProvider
- * @see DefaultPasswordTokenResponseClient
- * @deprecated The OAuth 2.0 Security Best Current Practice disallows the use of the
- * Resource Owner Password Credentials grant. See reference <a target="_blank" href=
- * "https://datatracker.ietf.org/doc/html/rfc9700#section-2.4">OAuth 2.0 Security Best
- * Current Practice.</a>
- */
-@Deprecated(since = "5.8", forRemoval = true)
-public final class PasswordOAuth2AuthorizedClientProvider implements OAuth2AuthorizedClientProvider {
-
-	private OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient = new DefaultPasswordTokenResponseClient();
-
-	private Duration clockSkew = Duration.ofSeconds(60);
-
-	private Clock clock = Clock.systemUTC();
-
-	/**
-	 * Attempt to authorize (or re-authorize) the
-	 * {@link OAuth2AuthorizationContext#getClientRegistration() client} in the provided
-	 * {@code context}. Returns {@code null} if authorization (or re-authorization) is not
-	 * supported, e.g. the client's {@link ClientRegistration#getAuthorizationGrantType()
-	 * authorization grant type} is not {@link AuthorizationGrantType#PASSWORD password}
-	 * OR the {@link OAuth2AuthorizationContext#USERNAME_ATTRIBUTE_NAME username} and/or
-	 * {@link OAuth2AuthorizationContext#PASSWORD_ATTRIBUTE_NAME password} attributes are
-	 * not available in the provided {@code context} OR the
-	 * {@link OAuth2AuthorizedClient#getAccessToken() access token} is not expired.
-	 *
-	 * <p>
-	 * The following {@link OAuth2AuthorizationContext#getAttributes() context attributes}
-	 * are supported:
-	 * <ol>
-	 * <li>{@link OAuth2AuthorizationContext#USERNAME_ATTRIBUTE_NAME} (required) - a
-	 * {@code String} value for the resource owner's username</li>
-	 * <li>{@link OAuth2AuthorizationContext#PASSWORD_ATTRIBUTE_NAME} (required) - a
-	 * {@code String} value for the resource owner's password</li>
-	 * </ol>
-	 * @param context the context that holds authorization-specific state for the client
-	 * @return the {@link OAuth2AuthorizedClient} or {@code null} if authorization (or
-	 * re-authorization) is not supported
-	 */
-	@Override
-	@Nullable
-	public OAuth2AuthorizedClient authorize(OAuth2AuthorizationContext context) {
-		Assert.notNull(context, "context cannot be null");
-		ClientRegistration clientRegistration = context.getClientRegistration();
-		OAuth2AuthorizedClient authorizedClient = context.getAuthorizedClient();
-		if (!AuthorizationGrantType.PASSWORD.equals(clientRegistration.getAuthorizationGrantType())) {
-			return null;
-		}
-		String username = context.getAttribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME);
-		String password = context.getAttribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME);
-		if (!StringUtils.hasText(username) || !StringUtils.hasText(password)) {
-			return null;
-		}
-		if (authorizedClient != null && !hasTokenExpired(authorizedClient.getAccessToken())) {
-			// If client is already authorized and access token is NOT expired than no
-			// need for re-authorization
-			return null;
-		}
-		if (authorizedClient != null && hasTokenExpired(authorizedClient.getAccessToken())
-				&& authorizedClient.getRefreshToken() != null) {
-			// If client is already authorized and access token is expired and a refresh
-			// token is available, than return and allow
-			// RefreshTokenOAuth2AuthorizedClientProvider to handle the refresh
-			return null;
-		}
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration, username,
-				password);
-		OAuth2AccessTokenResponse tokenResponse = getTokenResponse(clientRegistration, passwordGrantRequest);
-		return new OAuth2AuthorizedClient(clientRegistration, context.getPrincipal().getName(),
-				tokenResponse.getAccessToken(), tokenResponse.getRefreshToken());
-	}
-
-	private OAuth2AccessTokenResponse getTokenResponse(ClientRegistration clientRegistration,
-			OAuth2PasswordGrantRequest passwordGrantRequest) {
-		try {
-			return this.accessTokenResponseClient.getTokenResponse(passwordGrantRequest);
-		}
-		catch (OAuth2AuthorizationException ex) {
-			throw new ClientAuthorizationException(ex.getError(), clientRegistration.getRegistrationId(), ex);
-		}
-	}
-
-	private boolean hasTokenExpired(OAuth2Token token) {
-		return this.clock.instant().isAfter(token.getExpiresAt().minus(this.clockSkew));
-	}
-
-	/**
-	 * Sets the client used when requesting an access token credential at the Token
-	 * Endpoint for the {@code password} grant.
-	 * @param accessTokenResponseClient the client used when requesting an access token
-	 * credential at the Token Endpoint for the {@code password} grant
-	 */
-	public void setAccessTokenResponseClient(
-			OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient) {
-		Assert.notNull(accessTokenResponseClient, "accessTokenResponseClient cannot be null");
-		this.accessTokenResponseClient = accessTokenResponseClient;
-	}
-
-	/**
-	 * Sets the maximum acceptable clock skew, which is used when checking the
-	 * {@link OAuth2AuthorizedClient#getAccessToken() access token} expiry. The default is
-	 * 60 seconds.
-	 *
-	 * <p>
-	 * An access token is considered expired if
-	 * {@code OAuth2AccessToken#getExpiresAt() - clockSkew} is before the current time
-	 * {@code clock#instant()}.
-	 * @param clockSkew the maximum acceptable clock skew
-	 */
-	public void setClockSkew(Duration clockSkew) {
-		Assert.notNull(clockSkew, "clockSkew cannot be null");
-		Assert.isTrue(clockSkew.getSeconds() >= 0, "clockSkew must be >= 0");
-		this.clockSkew = clockSkew;
-	}
-
-	/**
-	 * Sets the {@link Clock} used in {@link Instant#now(Clock)} when checking the access
-	 * token expiry.
-	 * @param clock the clock
-	 */
-	public void setClock(Clock clock) {
-		Assert.notNull(clock, "clock cannot be null");
-		this.clock = clock;
-	}
-
-}

+ 0 - 161
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/PasswordReactiveOAuth2AuthorizedClientProvider.java

@@ -1,161 +0,0 @@
-/*
- * Copyright 2002-2025 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 java.time.Clock;
-import java.time.Duration;
-import java.time.Instant;
-
-import reactor.core.publisher.Mono;
-
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
-import org.springframework.security.oauth2.client.endpoint.WebClientReactivePasswordTokenResponseClient;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.core.AuthorizationGrantType;
-import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
-import org.springframework.security.oauth2.core.OAuth2Token;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-/**
- * An implementation of a {@link ReactiveOAuth2AuthorizedClientProvider} for the
- * {@link AuthorizationGrantType#PASSWORD password} grant.
- *
- * @author Joe Grandja
- * @since 5.2
- * @see ReactiveOAuth2AuthorizedClientProvider
- * @see WebClientReactivePasswordTokenResponseClient
- * @deprecated The OAuth 2.0 Security Best Current Practice disallows the use of the
- * Resource Owner Password Credentials grant. See reference <a target="_blank" href=
- * "https://datatracker.ietf.org/doc/html/rfc9700#section-2.4">OAuth 2.0 Security Best
- * Current Practice.</a>
- */
-@Deprecated(since = "5.8", forRemoval = true)
-public final class PasswordReactiveOAuth2AuthorizedClientProvider implements ReactiveOAuth2AuthorizedClientProvider {
-
-	private ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient = new WebClientReactivePasswordTokenResponseClient();
-
-	private Duration clockSkew = Duration.ofSeconds(60);
-
-	private Clock clock = Clock.systemUTC();
-
-	/**
-	 * Attempt to authorize (or re-authorize) the
-	 * {@link OAuth2AuthorizationContext#getClientRegistration() client} in the provided
-	 * {@code context}. Returns an empty {@code Mono} if authorization (or
-	 * re-authorization) is not supported, e.g. the client's
-	 * {@link ClientRegistration#getAuthorizationGrantType() authorization grant type} is
-	 * not {@link AuthorizationGrantType#PASSWORD password} OR the
-	 * {@link OAuth2AuthorizationContext#USERNAME_ATTRIBUTE_NAME username} and/or
-	 * {@link OAuth2AuthorizationContext#PASSWORD_ATTRIBUTE_NAME password} attributes are
-	 * not available in the provided {@code context} OR the
-	 * {@link OAuth2AuthorizedClient#getAccessToken() access token} is not expired.
-	 *
-	 * <p>
-	 * The following {@link OAuth2AuthorizationContext#getAttributes() context attributes}
-	 * are supported:
-	 * <ol>
-	 * <li>{@link OAuth2AuthorizationContext#USERNAME_ATTRIBUTE_NAME} (required) - a
-	 * {@code String} value for the resource owner's username</li>
-	 * <li>{@link OAuth2AuthorizationContext#PASSWORD_ATTRIBUTE_NAME} (required) - a
-	 * {@code String} value for the resource owner's password</li>
-	 * </ol>
-	 * @param context the context that holds authorization-specific state for the client
-	 * @return the {@link OAuth2AuthorizedClient} or an empty {@code Mono} if
-	 * authorization (or re-authorization) is not supported
-	 */
-	@Override
-	public Mono<OAuth2AuthorizedClient> authorize(OAuth2AuthorizationContext context) {
-		Assert.notNull(context, "context cannot be null");
-		ClientRegistration clientRegistration = context.getClientRegistration();
-		OAuth2AuthorizedClient authorizedClient = context.getAuthorizedClient();
-		if (!AuthorizationGrantType.PASSWORD.equals(clientRegistration.getAuthorizationGrantType())) {
-			return Mono.empty();
-		}
-		String username = context.getAttribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME);
-		String password = context.getAttribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME);
-		if (!StringUtils.hasText(username) || !StringUtils.hasText(password)) {
-			return Mono.empty();
-		}
-		if (authorizedClient != null && !hasTokenExpired(authorizedClient.getAccessToken())) {
-			// If client is already authorized and access token is NOT expired than no
-			// need for re-authorization
-			return Mono.empty();
-		}
-		if (authorizedClient != null && hasTokenExpired(authorizedClient.getAccessToken())
-				&& authorizedClient.getRefreshToken() != null) {
-			// If client is already authorized and access token is expired and a refresh
-			// token is available,
-			// than return and allow RefreshTokenReactiveOAuth2AuthorizedClientProvider to
-			// handle the refresh
-			return Mono.empty();
-		}
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration, username,
-				password);
-		return Mono.just(passwordGrantRequest)
-			.flatMap(this.accessTokenResponseClient::getTokenResponse)
-			.onErrorMap(OAuth2AuthorizationException.class,
-					(e) -> new ClientAuthorizationException(e.getError(), clientRegistration.getRegistrationId(), e))
-			.map((tokenResponse) -> new OAuth2AuthorizedClient(clientRegistration, context.getPrincipal().getName(),
-					tokenResponse.getAccessToken(), tokenResponse.getRefreshToken()));
-	}
-
-	private boolean hasTokenExpired(OAuth2Token token) {
-		return this.clock.instant().isAfter(token.getExpiresAt().minus(this.clockSkew));
-	}
-
-	/**
-	 * Sets the client used when requesting an access token credential at the Token
-	 * Endpoint for the {@code password} grant.
-	 * @param accessTokenResponseClient the client used when requesting an access token
-	 * credential at the Token Endpoint for the {@code password} grant
-	 */
-	public void setAccessTokenResponseClient(
-			ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient) {
-		Assert.notNull(accessTokenResponseClient, "accessTokenResponseClient cannot be null");
-		this.accessTokenResponseClient = accessTokenResponseClient;
-	}
-
-	/**
-	 * Sets the maximum acceptable clock skew, which is used when checking the
-	 * {@link OAuth2AuthorizedClient#getAccessToken() access token} expiry. The default is
-	 * 60 seconds.
-	 *
-	 * <p>
-	 * An access token is considered expired if
-	 * {@code OAuth2AccessToken#getExpiresAt() - clockSkew} is before the current time
-	 * {@code clock#instant()}.
-	 * @param clockSkew the maximum acceptable clock skew
-	 */
-	public void setClockSkew(Duration clockSkew) {
-		Assert.notNull(clockSkew, "clockSkew cannot be null");
-		Assert.isTrue(clockSkew.getSeconds() >= 0, "clockSkew must be >= 0");
-		this.clockSkew = clockSkew;
-	}
-
-	/**
-	 * Sets the {@link Clock} used in {@link Instant#now(Clock)} when checking the access
-	 * token expiry.
-	 * @param clock the clock
-	 */
-	public void setClock(Clock clock) {
-		Assert.notNull(clock, "clock cannot be null");
-		this.clock = clock;
-	}
-
-}

+ 4 - 112
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/ReactiveOAuth2AuthorizedClientProviderBuilder.java

@@ -26,7 +26,6 @@ import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
 import org.springframework.util.Assert;
@@ -35,10 +34,10 @@ import org.springframework.util.Assert;
  * A builder that builds a {@link DelegatingReactiveOAuth2AuthorizedClientProvider}
  * composed of one or more {@link ReactiveOAuth2AuthorizedClientProvider}(s) that
  * implement specific authorization grants. The supported authorization grants are
- * {@link #authorizationCode() authorization_code}, {@link #refreshToken() refresh_token},
- * {@link #clientCredentials() client_credentials} and {@link #password() password}. In
- * addition to the standard authorization grants, an implementation of an extension grant
- * may be supplied via {@link #provider(ReactiveOAuth2AuthorizedClientProvider)}.
+ * {@link #authorizationCode() authorization_code}, {@link #refreshToken() refresh_token}
+ * and {@link #clientCredentials() client_credentials}. In addition to the standard
+ * authorization grants, an implementation of an extension grant may be supplied via
+ * {@link #provider(ReactiveOAuth2AuthorizedClientProvider)}.
  *
  * @author Joe Grandja
  * @since 5.2
@@ -46,7 +45,6 @@ import org.springframework.util.Assert;
  * @see AuthorizationCodeReactiveOAuth2AuthorizedClientProvider
  * @see RefreshTokenReactiveOAuth2AuthorizedClientProvider
  * @see ClientCredentialsReactiveOAuth2AuthorizedClientProvider
- * @see PasswordReactiveOAuth2AuthorizedClientProvider
  * @see DelegatingReactiveOAuth2AuthorizedClientProvider
  */
 public final class ReactiveOAuth2AuthorizedClientProviderBuilder {
@@ -136,39 +134,6 @@ public final class ReactiveOAuth2AuthorizedClientProviderBuilder {
 		return ReactiveOAuth2AuthorizedClientProviderBuilder.this;
 	}
 
-	/**
-	 * Configures support for the {@code password} grant.
-	 * @return the {@link ReactiveOAuth2AuthorizedClientProviderBuilder}
-	 * @deprecated The OAuth 2.0 Security Best Current Practice disallows the use of the
-	 * Resource Owner Password Credentials grant. See reference <a target="_blank" href=
-	 * "https://datatracker.ietf.org/doc/html/rfc9700#section-2.4">OAuth 2.0 Security Best
-	 * Current Practice.</a>
-	 */
-	@Deprecated(since = "5.8", forRemoval = true)
-	public ReactiveOAuth2AuthorizedClientProviderBuilder password() {
-		this.builders.computeIfAbsent(PasswordReactiveOAuth2AuthorizedClientProvider.class,
-				(k) -> new PasswordGrantBuilder());
-		return ReactiveOAuth2AuthorizedClientProviderBuilder.this;
-	}
-
-	/**
-	 * Configures support for the {@code password} grant.
-	 * @param builderConsumer a {@code Consumer} of {@link PasswordGrantBuilder} used for
-	 * further configuration
-	 * @return the {@link ReactiveOAuth2AuthorizedClientProviderBuilder}
-	 * @deprecated The OAuth 2.0 Security Best Current Practice disallows the use of the
-	 * Resource Owner Password Credentials grant. See reference <a target="_blank" href=
-	 * "https://datatracker.ietf.org/doc/html/rfc9700#section-2.4">OAuth 2.0 Security Best
-	 * Current Practice.</a>
-	 */
-	@Deprecated(since = "5.8", forRemoval = true)
-	public ReactiveOAuth2AuthorizedClientProviderBuilder password(Consumer<PasswordGrantBuilder> builderConsumer) {
-		PasswordGrantBuilder builder = (PasswordGrantBuilder) this.builders
-			.computeIfAbsent(PasswordReactiveOAuth2AuthorizedClientProvider.class, (k) -> new PasswordGrantBuilder());
-		builderConsumer.accept(builder);
-		return ReactiveOAuth2AuthorizedClientProviderBuilder.this;
-	}
-
 	/**
 	 * Builds an instance of {@link DelegatingReactiveOAuth2AuthorizedClientProvider}
 	 * composed of one or more {@link ReactiveOAuth2AuthorizedClientProvider}(s).
@@ -282,79 +247,6 @@ public final class ReactiveOAuth2AuthorizedClientProviderBuilder {
 
 	}
 
-	/**
-	 * A builder for the {@code password} grant.
-	 */
-	public final class PasswordGrantBuilder implements Builder {
-
-		private ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient;
-
-		private Duration clockSkew;
-
-		private Clock clock;
-
-		private PasswordGrantBuilder() {
-		}
-
-		/**
-		 * Sets the client used when requesting an access token credential at the Token
-		 * Endpoint.
-		 * @param accessTokenResponseClient the client used when requesting an access
-		 * token credential at the Token Endpoint
-		 * @return the {@link PasswordGrantBuilder}
-		 */
-		public PasswordGrantBuilder accessTokenResponseClient(
-				ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient) {
-			this.accessTokenResponseClient = accessTokenResponseClient;
-			return this;
-		}
-
-		/**
-		 * Sets the maximum acceptable clock skew, which is used when checking the access
-		 * token expiry. An access token is considered expired if
-		 * {@code OAuth2Token#getExpiresAt() - clockSkew} is before the current time
-		 * {@code clock#instant()}.
-		 * @param clockSkew the maximum acceptable clock skew
-		 * @return the {@link PasswordGrantBuilder}
-		 * @see PasswordReactiveOAuth2AuthorizedClientProvider#setClockSkew(Duration)
-		 */
-		public PasswordGrantBuilder clockSkew(Duration clockSkew) {
-			this.clockSkew = clockSkew;
-			return this;
-		}
-
-		/**
-		 * Sets the {@link Clock} used in {@link Instant#now(Clock)} when checking the
-		 * access token expiry.
-		 * @param clock the clock
-		 * @return the {@link PasswordGrantBuilder}
-		 */
-		public PasswordGrantBuilder clock(Clock clock) {
-			this.clock = clock;
-			return this;
-		}
-
-		/**
-		 * Builds an instance of {@link PasswordReactiveOAuth2AuthorizedClientProvider}.
-		 * @return the {@link PasswordReactiveOAuth2AuthorizedClientProvider}
-		 */
-		@Override
-		public ReactiveOAuth2AuthorizedClientProvider build() {
-			PasswordReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = new PasswordReactiveOAuth2AuthorizedClientProvider();
-			if (this.accessTokenResponseClient != null) {
-				authorizedClientProvider.setAccessTokenResponseClient(this.accessTokenResponseClient);
-			}
-			if (this.clockSkew != null) {
-				authorizedClientProvider.setClockSkew(this.clockSkew);
-			}
-			if (this.clock != null) {
-				authorizedClientProvider.setClock(this.clock);
-			}
-			return authorizedClientProvider;
-		}
-
-	}
-
 	/**
 	 * A builder for the {@code refresh_token} grant.
 	 */

+ 1 - 2
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/AbstractWebClientReactiveOAuth2AccessTokenResponseClient.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -55,7 +55,6 @@ import org.springframework.web.reactive.function.client.WebClient.RequestHeaders
  * Endpoint</a>
  * @see WebClientReactiveAuthorizationCodeTokenResponseClient
  * @see WebClientReactiveClientCredentialsTokenResponseClient
- * @see WebClientReactivePasswordTokenResponseClient
  * @see WebClientReactiveRefreshTokenTokenResponseClient
  * @see DefaultOAuth2TokenRequestHeadersConverter
  */

+ 1 - 5
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultOAuth2TokenRequestParametersConverter.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -35,7 +35,6 @@ import org.springframework.util.MultiValueMap;
  * <li>{@code authorization_code}</li>
  * <li>{@code refresh_token}</li>
  * <li>{@code client_credentials}</li>
- * <li>{@code password}</li>
  * <li>{@code urn:ietf:params:oauth:grant-type:jwt-bearer}</li>
  * <li>{@code urn:ietf:params:oauth:grant-type:token-exchange}</li>
  * </ul>
@@ -93,9 +92,6 @@ public final class DefaultOAuth2TokenRequestParametersConverter<T extends Abstra
 			else if (grantRequest instanceof OAuth2RefreshTokenGrantRequest refreshTokenGrantRequest) {
 				return OAuth2RefreshTokenGrantRequest.defaultParameters(refreshTokenGrantRequest);
 			}
-			else if (grantRequest instanceof OAuth2PasswordGrantRequest passwordGrantRequest) {
-				return OAuth2PasswordGrantRequest.defaultParameters(passwordGrantRequest);
-			}
 			else if (grantRequest instanceof JwtBearerGrantRequest jwtBearerGrantRequest) {
 				return JwtBearerGrantRequest.defaultParameters(jwtBearerGrantRequest);
 			}

+ 0 - 136
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/DefaultPasswordTokenResponseClient.java

@@ -1,136 +0,0 @@
-/*
- * Copyright 2002-2025 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.endpoint;
-
-import java.util.Arrays;
-
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.http.RequestEntity;
-import org.springframework.http.ResponseEntity;
-import org.springframework.http.converter.FormHttpMessageConverter;
-import org.springframework.http.converter.HttpMessageConverter;
-import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler;
-import org.springframework.security.oauth2.core.AuthorizationGrantType;
-import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
-import org.springframework.security.oauth2.core.OAuth2Error;
-import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;
-import org.springframework.util.Assert;
-import org.springframework.web.client.ResponseErrorHandler;
-import org.springframework.web.client.RestClientException;
-import org.springframework.web.client.RestOperations;
-import org.springframework.web.client.RestTemplate;
-
-/**
- * The default implementation of an {@link OAuth2AccessTokenResponseClient} for the
- * {@link AuthorizationGrantType#PASSWORD password} grant. This implementation uses a
- * {@link RestOperations} when requesting an access token credential at the Authorization
- * Server's Token Endpoint.
- *
- * @author Joe Grandja
- * @since 5.2
- * @see OAuth2AccessTokenResponseClient
- * @see OAuth2PasswordGrantRequest
- * @see OAuth2AccessTokenResponse
- * @see <a target="_blank" href=
- * "https://tools.ietf.org/html/rfc6749#section-4.3.2">Section 4.3.2 Access Token Request
- * (Resource Owner Password Credentials Grant)</a>
- * @see <a target="_blank" href=
- * "https://tools.ietf.org/html/rfc6749#section-4.3.3">Section 4.3.3 Access Token Response
- * (Resource Owner Password Credentials Grant)</a>
- * @deprecated The OAuth 2.0 Security Best Current Practice disallows the use of the
- * Resource Owner Password Credentials grant. See reference <a target="_blank" href=
- * "https://datatracker.ietf.org/doc/html/rfc9700#section-2.4">OAuth 2.0 Security Best
- * Current Practice.</a>
- */
-@Deprecated(since = "5.8", forRemoval = true)
-public final class DefaultPasswordTokenResponseClient
-		implements OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> {
-
-	private static final String INVALID_TOKEN_RESPONSE_ERROR_CODE = "invalid_token_response";
-
-	private Converter<OAuth2PasswordGrantRequest, RequestEntity<?>> requestEntityConverter = new OAuth2PasswordGrantRequestEntityConverter();
-
-	private RestOperations restOperations;
-
-	public DefaultPasswordTokenResponseClient() {
-		RestTemplate restTemplate = new RestTemplate(
-				Arrays.asList(new FormHttpMessageConverter(), new OAuth2AccessTokenResponseHttpMessageConverter()));
-		restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
-		this.restOperations = restTemplate;
-	}
-
-	@Override
-	public OAuth2AccessTokenResponse getTokenResponse(OAuth2PasswordGrantRequest passwordGrantRequest) {
-		Assert.notNull(passwordGrantRequest, "passwordGrantRequest cannot be null");
-		RequestEntity<?> request = this.requestEntityConverter.convert(passwordGrantRequest);
-		ResponseEntity<OAuth2AccessTokenResponse> response = getResponse(request);
-		// As per spec, in Section 5.1 Successful Access Token Response
-		// https://tools.ietf.org/html/rfc6749#section-5.1
-		// If AccessTokenResponse.scope is empty, then we assume all requested scopes were
-		// granted.
-		// However, we use the explicit scopes returned in the response (if any).
-		return response.getBody();
-	}
-
-	private ResponseEntity<OAuth2AccessTokenResponse> getResponse(RequestEntity<?> request) {
-		try {
-			return this.restOperations.exchange(request, OAuth2AccessTokenResponse.class);
-		}
-		catch (RestClientException ex) {
-			OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE,
-					"An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: "
-							+ ex.getMessage(),
-					null);
-			throw new OAuth2AuthorizationException(oauth2Error, ex);
-		}
-	}
-
-	/**
-	 * Sets the {@link Converter} used for converting the
-	 * {@link OAuth2PasswordGrantRequest} to a {@link RequestEntity} representation of the
-	 * OAuth 2.0 Access Token Request.
-	 * @param requestEntityConverter the {@link Converter} used for converting to a
-	 * {@link RequestEntity} representation of the Access Token Request
-	 */
-	public void setRequestEntityConverter(
-			Converter<OAuth2PasswordGrantRequest, RequestEntity<?>> requestEntityConverter) {
-		Assert.notNull(requestEntityConverter, "requestEntityConverter cannot be null");
-		this.requestEntityConverter = requestEntityConverter;
-	}
-
-	/**
-	 * Sets the {@link RestOperations} used when requesting the OAuth 2.0 Access Token
-	 * Response.
-	 *
-	 * <p>
-	 * <b>NOTE:</b> At a minimum, the supplied {@code restOperations} must be configured
-	 * with the following:
-	 * <ol>
-	 * <li>{@link HttpMessageConverter}'s - {@link FormHttpMessageConverter} and
-	 * {@link OAuth2AccessTokenResponseHttpMessageConverter}</li>
-	 * <li>{@link ResponseErrorHandler} - {@link OAuth2ErrorResponseErrorHandler}</li>
-	 * </ol>
-	 * @param restOperations the {@link RestOperations} used when requesting the Access
-	 * Token Response
-	 */
-	public void setRestOperations(RestOperations restOperations) {
-		Assert.notNull(restOperations, "restOperations cannot be null");
-		this.restOperations = restOperations;
-	}
-
-}

+ 0 - 100
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/OAuth2PasswordGrantRequest.java

@@ -1,100 +0,0 @@
-/*
- * Copyright 2002-2025 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.endpoint;
-
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.core.AuthorizationGrantType;
-import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
-import org.springframework.util.Assert;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-import org.springframework.util.StringUtils;
-
-/**
- * An OAuth 2.0 Resource Owner Password Credentials Grant request that holds the resource
- * owner's credentials.
- *
- * @author Joe Grandja
- * @since 5.2
- * @see AbstractOAuth2AuthorizationGrantRequest
- * @see <a target="_blank" href=
- * "https://tools.ietf.org/html/rfc6749#section-1.3.3">Section 1.3.3 Resource Owner
- * Password Credentials</a>
- * @deprecated The OAuth 2.0 Security Best Current Practice disallows the use of the
- * Resource Owner Password Credentials grant. See reference <a target="_blank" href=
- * "https://datatracker.ietf.org/doc/html/rfc9700#section-2.4">OAuth 2.0 Security Best
- * Current Practice.</a>
- */
-@Deprecated(since = "5.8", forRemoval = true)
-public class OAuth2PasswordGrantRequest extends AbstractOAuth2AuthorizationGrantRequest {
-
-	private final String username;
-
-	private final String password;
-
-	/**
-	 * Constructs an {@code OAuth2PasswordGrantRequest} using the provided parameters.
-	 * @param clientRegistration the client registration
-	 * @param username the resource owner's username
-	 * @param password the resource owner's password
-	 */
-	public OAuth2PasswordGrantRequest(ClientRegistration clientRegistration, String username, String password) {
-		super(AuthorizationGrantType.PASSWORD, clientRegistration);
-		Assert.isTrue(AuthorizationGrantType.PASSWORD.equals(clientRegistration.getAuthorizationGrantType()),
-				"clientRegistration.authorizationGrantType must be AuthorizationGrantType.PASSWORD");
-		Assert.hasText(username, "username cannot be empty");
-		Assert.hasText(password, "password cannot be empty");
-		this.username = username;
-		this.password = password;
-	}
-
-	/**
-	 * Returns the resource owner's username.
-	 * @return the resource owner's username
-	 */
-	public String getUsername() {
-		return this.username;
-	}
-
-	/**
-	 * Returns the resource owner's password.
-	 * @return the resource owner's password
-	 */
-	public String getPassword() {
-		return this.password;
-	}
-
-	/**
-	 * Populate default parameters for the Password Grant.
-	 * @param grantRequest the authorization grant request
-	 * @return a {@link MultiValueMap} of the parameters used in the OAuth 2.0 Access
-	 * Token Request body
-	 */
-	static MultiValueMap<String, String> defaultParameters(OAuth2PasswordGrantRequest grantRequest) {
-		ClientRegistration clientRegistration = grantRequest.getClientRegistration();
-		MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
-		if (!CollectionUtils.isEmpty(clientRegistration.getScopes())) {
-			parameters.set(OAuth2ParameterNames.SCOPE,
-					StringUtils.collectionToDelimitedString(clientRegistration.getScopes(), " "));
-		}
-		parameters.set(OAuth2ParameterNames.USERNAME, grantRequest.getUsername());
-		parameters.set(OAuth2ParameterNames.PASSWORD, grantRequest.getPassword());
-		return parameters;
-	}
-
-}

+ 0 - 63
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/OAuth2PasswordGrantRequestEntityConverter.java

@@ -1,63 +0,0 @@
-/*
- * Copyright 2002-2025 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.endpoint;
-
-import org.springframework.http.RequestEntity;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
-import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-import org.springframework.util.StringUtils;
-
-/**
- * An implementation of an {@link AbstractOAuth2AuthorizationGrantRequestEntityConverter}
- * that converts the provided {@link OAuth2PasswordGrantRequest} to a
- * {@link RequestEntity} representation of an OAuth 2.0 Access Token Request for the
- * Resource Owner Password Credentials Grant.
- *
- * @author Joe Grandja
- * @since 5.2
- * @see AbstractOAuth2AuthorizationGrantRequestEntityConverter
- * @see OAuth2PasswordGrantRequest
- * @see RequestEntity
- * @deprecated Use {@link DefaultOAuth2TokenRequestParametersConverter} instead
- */
-@Deprecated(since = "6.4", forRemoval = true)
-public class OAuth2PasswordGrantRequestEntityConverter
-		extends AbstractOAuth2AuthorizationGrantRequestEntityConverter<OAuth2PasswordGrantRequest> {
-
-	@Override
-	protected MultiValueMap<String, String> createParameters(OAuth2PasswordGrantRequest passwordGrantRequest) {
-		ClientRegistration clientRegistration = passwordGrantRequest.getClientRegistration();
-		MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
-		parameters.add(OAuth2ParameterNames.GRANT_TYPE, passwordGrantRequest.getGrantType().getValue());
-		parameters.add(OAuth2ParameterNames.USERNAME, passwordGrantRequest.getUsername());
-		parameters.add(OAuth2ParameterNames.PASSWORD, passwordGrantRequest.getPassword());
-		if (!CollectionUtils.isEmpty(clientRegistration.getScopes())) {
-			parameters.add(OAuth2ParameterNames.SCOPE,
-					StringUtils.collectionToDelimitedString(clientRegistration.getScopes(), " "));
-		}
-		if (ClientAuthenticationMethod.CLIENT_SECRET_POST.equals(clientRegistration.getClientAuthenticationMethod())) {
-			parameters.add(OAuth2ParameterNames.CLIENT_ID, clientRegistration.getClientId());
-			parameters.add(OAuth2ParameterNames.CLIENT_SECRET, clientRegistration.getClientSecret());
-		}
-		return parameters;
-	}
-
-}

+ 0 - 49
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/WebClientReactivePasswordTokenResponseClient.java

@@ -1,49 +0,0 @@
-/*
- * Copyright 2002-2025 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.endpoint;
-
-import org.springframework.security.oauth2.core.AuthorizationGrantType;
-import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.web.reactive.function.client.WebClient;
-
-/**
- * An implementation of a {@link ReactiveOAuth2AccessTokenResponseClient} for the
- * {@link AuthorizationGrantType#PASSWORD password} grant. This implementation uses
- * {@link WebClient} when requesting an access token credential at the Authorization
- * Server's Token Endpoint.
- *
- * @author Joe Grandja
- * @since 5.2
- * @see ReactiveOAuth2AccessTokenResponseClient
- * @see OAuth2PasswordGrantRequest
- * @see OAuth2AccessTokenResponse
- * @see <a target="_blank" href=
- * "https://tools.ietf.org/html/rfc6749#section-4.3.2">Section 4.3.2 Access Token Request
- * (Resource Owner Password Credentials Grant)</a>
- * @see <a target="_blank" href=
- * "https://tools.ietf.org/html/rfc6749#section-4.3.3">Section 4.3.3 Access Token Response
- * (Resource Owner Password Credentials Grant)</a>
- * @deprecated The OAuth 2.0 Security Best Current Practice disallows the use of the
- * Resource Owner Password Credentials grant. See reference <a target="_blank" href=
- * "https://datatracker.ietf.org/doc/html/rfc9700#section-2.4">OAuth 2.0 Security Best
- * Current Practice.</a>
- */
-@Deprecated(since = "5.8", forRemoval = true)
-public final class WebClientReactivePasswordTokenResponseClient
-		extends AbstractWebClientReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> {
-
-}

+ 0 - 3
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/jackson2/StdConverters.java

@@ -66,9 +66,6 @@ abstract class StdConverters {
 			if (AuthorizationGrantType.CLIENT_CREDENTIALS.getValue().equalsIgnoreCase(value)) {
 				return AuthorizationGrantType.CLIENT_CREDENTIALS;
 			}
-			if (AuthorizationGrantType.PASSWORD.getValue().equalsIgnoreCase(value)) {
-				return AuthorizationGrantType.PASSWORD;
-			}
 			return new AuthorizationGrantType(value);
 		}
 

+ 1 - 12
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistration.java

@@ -346,7 +346,7 @@ public final class ClientRegistration implements Serializable {
 
 		private static final List<AuthorizationGrantType> AUTHORIZATION_GRANT_TYPES = Arrays.asList(
 				AuthorizationGrantType.AUTHORIZATION_CODE, AuthorizationGrantType.CLIENT_CREDENTIALS,
-				AuthorizationGrantType.REFRESH_TOKEN, AuthorizationGrantType.PASSWORD);
+				AuthorizationGrantType.REFRESH_TOKEN);
 
 		private String registrationId;
 
@@ -630,9 +630,6 @@ public final class ClientRegistration implements Serializable {
 			if (AuthorizationGrantType.CLIENT_CREDENTIALS.equals(this.authorizationGrantType)) {
 				this.validateClientCredentialsGrantType();
 			}
-			else if (AuthorizationGrantType.PASSWORD.equals(this.authorizationGrantType)) {
-				this.validatePasswordGrantType();
-			}
 			else if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(this.authorizationGrantType)) {
 				this.validateAuthorizationCodeGrantType();
 			}
@@ -697,14 +694,6 @@ public final class ClientRegistration implements Serializable {
 			Assert.hasText(this.tokenUri, "tokenUri cannot be empty");
 		}
 
-		private void validatePasswordGrantType() {
-			Assert.isTrue(AuthorizationGrantType.PASSWORD.equals(this.authorizationGrantType),
-					() -> "authorizationGrantType must be " + AuthorizationGrantType.PASSWORD.getValue());
-			Assert.hasText(this.registrationId, "registrationId cannot be empty");
-			Assert.hasText(this.clientId, "clientId cannot be empty");
-			Assert.hasText(this.tokenUri, "tokenUri cannot be empty");
-		}
-
 		private void validateAuthorizationGrantTypes() {
 			for (AuthorizationGrantType authorizationGrantType : AUTHORIZATION_GRANT_TYPES) {
 				if (authorizationGrantType.getValue().equalsIgnoreCase(this.authorizationGrantType.getValue())

+ 1 - 2
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManager.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -92,7 +92,6 @@ public final class DefaultOAuth2AuthorizedClientManager implements OAuth2Authori
 			.authorizationCode()
 			.refreshToken()
 			.clientCredentials()
-			.password()
 			.build();
 	// @formatter:on
 

+ 1 - 2
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManager.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -98,7 +98,6 @@ public final class DefaultReactiveOAuth2AuthorizedClientManager implements React
 			.authorizationCode()
 			.refreshToken()
 			.clientCredentials()
-			.password()
 			.build();
 	// @formatter:on
 

+ 9 - 47
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/OAuth2AuthorizedClientProviderBuilderTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -18,7 +18,6 @@ package org.springframework.security.oauth2.client;
 
 import java.time.Duration;
 import java.time.Instant;
-import java.util.List;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -29,7 +28,6 @@ import org.springframework.http.MediaType;
 import org.springframework.http.converter.FormHttpMessageConverter;
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.client.endpoint.DefaultPasswordTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.RestClientClientCredentialsTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.RestClientRefreshTokenTokenResponseClient;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
@@ -40,7 +38,6 @@ import org.springframework.security.oauth2.core.http.converter.OAuth2AccessToken
 import org.springframework.test.web.client.ExpectedCount;
 import org.springframework.test.web.client.MockRestServiceServer;
 import org.springframework.web.client.RestClient;
-import org.springframework.web.client.RestTemplate;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -64,26 +61,23 @@ public class OAuth2AuthorizedClientProviderBuilderTests {
 
 	private RestClientRefreshTokenTokenResponseClient refreshTokenTokenResponseClient;
 
-	private DefaultPasswordTokenResponseClient passwordTokenResponseClient;
-
 	private Authentication principal;
 
 	private MockRestServiceServer server;
 
 	@BeforeEach
 	public void setup() {
-		// TODO: Use of RestTemplate in these tests can be removed when
-		// DefaultPasswordTokenResponseClient is removed.
-		RestTemplate accessTokenClient = new RestTemplate(
-				List.of(new FormHttpMessageConverter(), new OAuth2AccessTokenResponseHttpMessageConverter()));
-		this.server = MockRestServiceServer.bindTo(accessTokenClient).build();
-		RestClient restClient = RestClient.create(accessTokenClient);
+		RestClient.Builder restClientBuilder = RestClient.builder().messageConverters((messageConverters) -> {
+			messageConverters.clear();
+			messageConverters.add(new FormHttpMessageConverter());
+			messageConverters.add(new OAuth2AccessTokenResponseHttpMessageConverter());
+		});
+		this.server = MockRestServiceServer.bindTo(restClientBuilder).build();
+		RestClient restClient = restClientBuilder.build();
 		this.refreshTokenTokenResponseClient = new RestClientRefreshTokenTokenResponseClient();
 		this.refreshTokenTokenResponseClient.setRestClient(restClient);
 		this.clientCredentialsTokenResponseClient = new RestClientClientCredentialsTokenResponseClient();
 		this.clientCredentialsTokenResponseClient.setRestClient(restClient);
-		this.passwordTokenResponseClient = new DefaultPasswordTokenResponseClient();
-		this.passwordTokenResponseClient.setRestOperations(accessTokenClient);
 		this.principal = new TestingAuthenticationToken("principal", "password");
 	}
 
@@ -148,36 +142,15 @@ public class OAuth2AuthorizedClientProviderBuilderTests {
 		this.server.verify();
 	}
 
-	@Test
-	public void buildWhenPasswordProviderThenProviderAuthorizes() {
-		mockAccessTokenResponse(once());
-
-		// @formatter:off
-		OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
-				.password((configurer) -> configurer.accessTokenResponseClient(this.passwordTokenResponseClient))
-				.build();
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withClientRegistration(TestClientRegistrations.password().build())
-				.principal(this.principal)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.build();
-		// @formatter:on
-		OAuth2AuthorizedClient authorizedClient = authorizedClientProvider.authorize(authorizationContext);
-		assertThat(authorizedClient).isNotNull();
-		this.server.verify();
-	}
-
 	@Test
 	public void buildWhenAllProvidersThenProvidersAuthorize() {
-		mockAccessTokenResponse(times(3));
+		mockAccessTokenResponse(times(2));
 
 		OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
 			.authorizationCode()
 			.refreshToken((configurer) -> configurer.accessTokenResponseClient(this.refreshTokenTokenResponseClient))
 			.clientCredentials(
 					(configurer) -> configurer.accessTokenResponseClient(this.clientCredentialsTokenResponseClient))
-			.password((configurer) -> configurer.accessTokenResponseClient(this.passwordTokenResponseClient))
 			.build();
 		ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
 		// authorization_code
@@ -207,17 +180,6 @@ public class OAuth2AuthorizedClientProviderBuilderTests {
 		// @formatter:on
 		authorizedClient = authorizedClientProvider.authorize(clientCredentialsContext);
 		assertThat(authorizedClient).isNotNull();
-		// password
-		// @formatter:off
-		OAuth2AuthorizationContext passwordContext = OAuth2AuthorizationContext
-				.withClientRegistration(TestClientRegistrations.password().build())
-				.principal(this.principal)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.build();
-		// @formatter:on
-		authorizedClient = authorizedClientProvider.authorize(passwordContext);
-		assertThat(authorizedClient).isNotNull();
 		this.server.verify();
 	}
 

+ 0 - 240
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/PasswordOAuth2AuthorizedClientProviderTests.java

@@ -1,240 +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;
-
-import java.time.Duration;
-import java.time.Instant;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.security.authentication.TestingAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
-import org.springframework.security.oauth2.core.OAuth2AccessToken;
-import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
-import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-
-/**
- * Tests for {@link PasswordOAuth2AuthorizedClientProvider}.
- *
- * @author Joe Grandja
- */
-public class PasswordOAuth2AuthorizedClientProviderTests {
-
-	private PasswordOAuth2AuthorizedClientProvider authorizedClientProvider;
-
-	private OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient;
-
-	private ClientRegistration clientRegistration;
-
-	private Authentication principal;
-
-	@BeforeEach
-	public void setup() {
-		this.authorizedClientProvider = new PasswordOAuth2AuthorizedClientProvider();
-		this.accessTokenResponseClient = mock(OAuth2AccessTokenResponseClient.class);
-		this.authorizedClientProvider.setAccessTokenResponseClient(this.accessTokenResponseClient);
-		this.clientRegistration = TestClientRegistrations.password().build();
-		this.principal = new TestingAuthenticationToken("principal", "password");
-	}
-
-	@Test
-	public void setAccessTokenResponseClientWhenClientIsNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException()
-			.isThrownBy(() -> this.authorizedClientProvider.setAccessTokenResponseClient(null))
-			.withMessage("accessTokenResponseClient cannot be null");
-	}
-
-	@Test
-	public void setClockSkewWhenNullThenThrowIllegalArgumentException() {
-		// @formatter:off
-		assertThatIllegalArgumentException()
-				.isThrownBy(() -> this.authorizedClientProvider.setClockSkew(null))
-				.withMessage("clockSkew cannot be null");
-		// @formatter:on
-	}
-
-	@Test
-	public void setClockSkewWhenNegativeSecondsThenThrowIllegalArgumentException() {
-		// @formatter:off
-		assertThatIllegalArgumentException()
-				.isThrownBy(() -> this.authorizedClientProvider.setClockSkew(Duration.ofSeconds(-1)))
-				.withMessage("clockSkew must be >= 0");
-		// @formatter:on
-	}
-
-	@Test
-	public void setClockWhenNullThenThrowIllegalArgumentException() {
-		// @formatter:off
-		assertThatIllegalArgumentException()
-				.isThrownBy(() -> this.authorizedClientProvider.setClock(null))
-				.withMessage("clock cannot be null");
-		// @formatter:on
-	}
-
-	@Test
-	public void authorizeWhenContextIsNullThenThrowIllegalArgumentException() {
-		// @formatter:off
-		assertThatIllegalArgumentException()
-				.isThrownBy(() -> this.authorizedClientProvider.authorize(null))
-				.withMessage("context cannot be null");
-		// @formatter:on
-	}
-
-	@Test
-	public void authorizeWhenNotPasswordThenUnableToAuthorize() {
-		ClientRegistration clientRegistration = TestClientRegistrations.clientCredentials().build();
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withClientRegistration(clientRegistration)
-				.principal(this.principal)
-				.build();
-		// @formatter:on
-		assertThat(this.authorizedClientProvider.authorize(authorizationContext)).isNull();
-	}
-
-	@Test
-	public void authorizeWhenPasswordAndNotAuthorizedAndEmptyUsernameThenUnableToAuthorize() {
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withClientRegistration(this.clientRegistration)
-				.principal(this.principal)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, null)
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.build();
-		// @formatter:on
-		assertThat(this.authorizedClientProvider.authorize(authorizationContext)).isNull();
-	}
-
-	@Test
-	public void authorizeWhenPasswordAndNotAuthorizedAndEmptyPasswordThenUnableToAuthorize() {
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withClientRegistration(this.clientRegistration)
-				.principal(this.principal)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, null)
-				.build();
-		// @formatter:on
-		assertThat(this.authorizedClientProvider.authorize(authorizationContext)).isNull();
-	}
-
-	@Test
-	public void authorizeWhenPasswordAndNotAuthorizedThenAuthorize() {
-		OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
-		given(this.accessTokenResponseClient.getTokenResponse(any())).willReturn(accessTokenResponse);
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withClientRegistration(this.clientRegistration)
-				.principal(this.principal)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.build();
-		// @formatter:on
-		OAuth2AuthorizedClient authorizedClient = this.authorizedClientProvider.authorize(authorizationContext);
-		assertThat(authorizedClient.getClientRegistration()).isSameAs(this.clientRegistration);
-		assertThat(authorizedClient.getPrincipalName()).isEqualTo(this.principal.getName());
-		assertThat(authorizedClient.getAccessToken()).isEqualTo(accessTokenResponse.getAccessToken());
-	}
-
-	@Test
-	public void authorizeWhenPasswordAndAuthorizedWithoutRefreshTokenAndTokenExpiredThenReauthorize() {
-		Instant issuedAt = Instant.now().minus(Duration.ofDays(1));
-		Instant expiresAt = issuedAt.plus(Duration.ofMinutes(60));
-		OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER,
-				"access-token-expired", issuedAt, expiresAt);
-		OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.clientRegistration,
-				this.principal.getName(), accessToken); // without refresh token
-		OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
-		given(this.accessTokenResponseClient.getTokenResponse(any())).willReturn(accessTokenResponse);
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withAuthorizedClient(authorizedClient)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.principal(this.principal)
-				.build();
-		// @formatter:on
-		authorizedClient = this.authorizedClientProvider.authorize(authorizationContext);
-		assertThat(authorizedClient.getClientRegistration()).isSameAs(this.clientRegistration);
-		assertThat(authorizedClient.getPrincipalName()).isEqualTo(this.principal.getName());
-		assertThat(authorizedClient.getAccessToken()).isEqualTo(accessTokenResponse.getAccessToken());
-	}
-
-	@Test
-	public void authorizeWhenPasswordAndAuthorizedWithRefreshTokenAndTokenExpiredThenNotReauthorize() {
-		Instant issuedAt = Instant.now().minus(Duration.ofDays(1));
-		Instant expiresAt = issuedAt.plus(Duration.ofMinutes(60));
-		OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER,
-				"access-token-expired", issuedAt, expiresAt);
-		OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.clientRegistration,
-				this.principal.getName(), accessToken, TestOAuth2RefreshTokens.refreshToken()); // with
-																								// refresh
-																								// token
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withAuthorizedClient(authorizedClient)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.principal(this.principal)
-				.build();
-		// @formatter:on
-		assertThat(this.authorizedClientProvider.authorize(authorizationContext)).isNull();
-	}
-
-	// gh-7511
-	@Test
-	public void authorizeWhenPasswordAndAuthorizedAndTokenNotExpiredButClockSkewForcesExpiryThenReauthorize() {
-		Instant now = Instant.now();
-		Instant issuedAt = now.minus(Duration.ofMinutes(60));
-		Instant expiresAt = now.plus(Duration.ofMinutes(1));
-		OAuth2AccessToken expiresInOneMinAccessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER,
-				"access-token-1234", issuedAt, expiresAt);
-		OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.clientRegistration,
-				this.principal.getName(), expiresInOneMinAccessToken); // without refresh
-																		// token
-		// Shorten the lifespan of the access token by 90 seconds, which will ultimately
-		// force it to expire on the client
-		this.authorizedClientProvider.setClockSkew(Duration.ofSeconds(90));
-		OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
-		given(this.accessTokenResponseClient.getTokenResponse(any())).willReturn(accessTokenResponse);
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withAuthorizedClient(authorizedClient)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.principal(this.principal)
-				.build();
-		// @formatter:on
-		OAuth2AuthorizedClient reauthorizedClient = this.authorizedClientProvider.authorize(authorizationContext);
-		assertThat(reauthorizedClient.getClientRegistration()).isSameAs(this.clientRegistration);
-		assertThat(reauthorizedClient.getPrincipalName()).isEqualTo(this.principal.getName());
-		assertThat(reauthorizedClient.getAccessToken()).isEqualTo(accessTokenResponse.getAccessToken());
-	}
-
-}

+ 0 - 242
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/PasswordReactiveOAuth2AuthorizedClientProviderTests.java

@@ -1,242 +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;
-
-import java.time.Duration;
-import java.time.Instant;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import reactor.core.publisher.Mono;
-
-import org.springframework.security.authentication.TestingAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
-import org.springframework.security.oauth2.core.OAuth2AccessToken;
-import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
-import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-
-/**
- * Tests for {@link PasswordReactiveOAuth2AuthorizedClientProvider}.
- *
- * @author Joe Grandja
- */
-public class PasswordReactiveOAuth2AuthorizedClientProviderTests {
-
-	private PasswordReactiveOAuth2AuthorizedClientProvider authorizedClientProvider;
-
-	private ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient;
-
-	private ClientRegistration clientRegistration;
-
-	private Authentication principal;
-
-	@BeforeEach
-	public void setup() {
-		this.authorizedClientProvider = new PasswordReactiveOAuth2AuthorizedClientProvider();
-		this.accessTokenResponseClient = mock(ReactiveOAuth2AccessTokenResponseClient.class);
-		this.authorizedClientProvider.setAccessTokenResponseClient(this.accessTokenResponseClient);
-		this.clientRegistration = TestClientRegistrations.password().build();
-		this.principal = new TestingAuthenticationToken("principal", "password");
-	}
-
-	@Test
-	public void setAccessTokenResponseClientWhenClientIsNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException()
-			.isThrownBy(() -> this.authorizedClientProvider.setAccessTokenResponseClient(null))
-			.withMessage("accessTokenResponseClient cannot be null");
-	}
-
-	@Test
-	public void setClockSkewWhenNullThenThrowIllegalArgumentException() {
-		// @formatter:off
-		assertThatIllegalArgumentException()
-				.isThrownBy(() -> this.authorizedClientProvider.setClockSkew(null))
-				.withMessage("clockSkew cannot be null");
-		// @formatter:on
-	}
-
-	@Test
-	public void setClockSkewWhenNegativeSecondsThenThrowIllegalArgumentException() {
-		// @formatter:off
-		assertThatIllegalArgumentException()
-				.isThrownBy(() -> this.authorizedClientProvider.setClockSkew(Duration.ofSeconds(-1)))
-				.withMessage("clockSkew must be >= 0");
-		// @formatter:on
-	}
-
-	@Test
-	public void setClockWhenNullThenThrowIllegalArgumentException() {
-		// @formatter:off
-		assertThatIllegalArgumentException()
-				.isThrownBy(() -> this.authorizedClientProvider.setClock(null))
-				.withMessage("clock cannot be null");
-		// @formatter:on
-	}
-
-	@Test
-	public void authorizeWhenContextIsNullThenThrowIllegalArgumentException() {
-		// @formatter:off
-		assertThatIllegalArgumentException()
-				.isThrownBy(() -> this.authorizedClientProvider.authorize(null).block())
-				.withMessage("context cannot be null");
-		// @formatter:on
-	}
-
-	@Test
-	public void authorizeWhenNotPasswordThenUnableToAuthorize() {
-		ClientRegistration clientRegistration = TestClientRegistrations.clientCredentials().build();
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withClientRegistration(clientRegistration)
-				.principal(this.principal).
-				build();
-		// @formatter:on
-		assertThat(this.authorizedClientProvider.authorize(authorizationContext).block()).isNull();
-	}
-
-	@Test
-	public void authorizeWhenPasswordAndNotAuthorizedAndEmptyUsernameThenUnableToAuthorize() {
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withClientRegistration(this.clientRegistration)
-				.principal(this.principal)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, null)
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.build();
-		// @formatter:on
-		assertThat(this.authorizedClientProvider.authorize(authorizationContext).block()).isNull();
-	}
-
-	@Test
-	public void authorizeWhenPasswordAndNotAuthorizedAndEmptyPasswordThenUnableToAuthorize() {
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withClientRegistration(this.clientRegistration)
-				.principal(this.principal)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, null)
-				.build();
-		// @formatter:on
-		assertThat(this.authorizedClientProvider.authorize(authorizationContext).block()).isNull();
-	}
-
-	@Test
-	public void authorizeWhenPasswordAndNotAuthorizedThenAuthorize() {
-		OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
-		given(this.accessTokenResponseClient.getTokenResponse(any())).willReturn(Mono.just(accessTokenResponse));
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withClientRegistration(this.clientRegistration)
-				.principal(this.principal)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.build();
-		// @formatter:on
-		OAuth2AuthorizedClient authorizedClient = this.authorizedClientProvider.authorize(authorizationContext).block();
-		assertThat(authorizedClient.getClientRegistration()).isSameAs(this.clientRegistration);
-		assertThat(authorizedClient.getPrincipalName()).isEqualTo(this.principal.getName());
-		assertThat(authorizedClient.getAccessToken()).isEqualTo(accessTokenResponse.getAccessToken());
-	}
-
-	@Test
-	public void authorizeWhenPasswordAndAuthorizedWithoutRefreshTokenAndTokenExpiredThenReauthorize() {
-		Instant issuedAt = Instant.now().minus(Duration.ofDays(1));
-		Instant expiresAt = issuedAt.plus(Duration.ofMinutes(60));
-		OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER,
-				"access-token-expired", issuedAt, expiresAt);
-		OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.clientRegistration,
-				this.principal.getName(), accessToken); // without refresh token
-		OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
-		given(this.accessTokenResponseClient.getTokenResponse(any())).willReturn(Mono.just(accessTokenResponse));
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withAuthorizedClient(authorizedClient)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.principal(this.principal)
-				.build();
-		// @formatter:on
-		authorizedClient = this.authorizedClientProvider.authorize(authorizationContext).block();
-		assertThat(authorizedClient.getClientRegistration()).isSameAs(this.clientRegistration);
-		assertThat(authorizedClient.getPrincipalName()).isEqualTo(this.principal.getName());
-		assertThat(authorizedClient.getAccessToken()).isEqualTo(accessTokenResponse.getAccessToken());
-	}
-
-	@Test
-	public void authorizeWhenPasswordAndAuthorizedWithRefreshTokenAndTokenExpiredThenNotReauthorize() {
-		Instant issuedAt = Instant.now().minus(Duration.ofDays(1));
-		Instant expiresAt = issuedAt.plus(Duration.ofMinutes(60));
-		OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER,
-				"access-token-expired", issuedAt, expiresAt);
-		OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.clientRegistration,
-				this.principal.getName(), accessToken, TestOAuth2RefreshTokens.refreshToken()); // with
-																								// refresh
-																								// token
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withAuthorizedClient(authorizedClient)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.principal(this.principal)
-				.build();
-		// @formatter:on
-		assertThat(this.authorizedClientProvider.authorize(authorizationContext).block()).isNull();
-	}
-
-	// gh-7511
-	@Test
-	public void authorizeWhenPasswordAndAuthorizedAndTokenNotExpiredButClockSkewForcesExpiryThenReauthorize() {
-		Instant now = Instant.now();
-		Instant issuedAt = now.minus(Duration.ofMinutes(60));
-		Instant expiresAt = now.minus(Duration.ofMinutes(1));
-		OAuth2AccessToken expiresInOneMinAccessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER,
-				"access-token-1234", issuedAt, expiresAt);
-		OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.clientRegistration,
-				this.principal.getName(), expiresInOneMinAccessToken); // without refresh
-																		// token
-		// Shorten the lifespan of the access token by 90 seconds, which will ultimately
-		// force it to expire on the client
-		this.authorizedClientProvider.setClockSkew(Duration.ofSeconds(90));
-		OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
-		given(this.accessTokenResponseClient.getTokenResponse(any())).willReturn(Mono.just(accessTokenResponse));
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withAuthorizedClient(authorizedClient)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.principal(this.principal)
-				.build();
-		// @formatter:on
-		OAuth2AuthorizedClient reauthorizedClient = this.authorizedClientProvider.authorize(authorizationContext)
-			.block();
-		assertThat(reauthorizedClient.getClientRegistration()).isSameAs(this.clientRegistration);
-		assertThat(reauthorizedClient.getPrincipalName()).isEqualTo(this.principal.getName());
-		assertThat(reauthorizedClient.getAccessToken()).isEqualTo(accessTokenResponse.getAccessToken());
-	}
-
-}

+ 1 - 45
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/ReactiveOAuth2AuthorizedClientProviderBuilderTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -145,33 +145,6 @@ public class ReactiveOAuth2AuthorizedClientProviderBuilderTests {
 		assertThat(formParameters).contains("grant_type=client_credentials");
 	}
 
-	@Test
-	public void buildWhenPasswordProviderThenProviderAuthorizes() throws Exception {
-		String accessTokenSuccessResponse = "{\n" + "	\"access_token\": \"access-token-1234\",\n"
-				+ "   \"token_type\": \"bearer\",\n" + "   \"expires_in\": \"3600\"\n" + "}\n";
-		this.server.enqueue(jsonResponse(accessTokenSuccessResponse));
-		ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder
-			.builder()
-			.password()
-			.build();
-		// @formatter:off
-		OAuth2AuthorizationContext authorizationContext = OAuth2AuthorizationContext
-				.withClientRegistration(
-						this.clientRegistrationBuilder.authorizationGrantType(AuthorizationGrantType.PASSWORD).build())
-				.principal(this.principal)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.build();
-		OAuth2AuthorizedClient authorizedClient = authorizedClientProvider.authorize(authorizationContext)
-				.block();
-		// @formatter:on
-		assertThat(authorizedClient).isNotNull();
-		assertThat(this.server.getRequestCount()).isEqualTo(1);
-		RecordedRequest recordedRequest = this.server.takeRequest();
-		String formParameters = recordedRequest.getBody().readUtf8();
-		assertThat(formParameters).contains("grant_type=password");
-	}
-
 	@Test
 	public void buildWhenAllProvidersThenProvidersAuthorize() throws Exception {
 		String accessTokenSuccessResponse = "{\n" + "	\"access_token\": \"access-token-1234\",\n"
@@ -184,7 +157,6 @@ public class ReactiveOAuth2AuthorizedClientProviderBuilderTests {
 			.authorizationCode()
 			.refreshToken()
 			.clientCredentials()
-			.password()
 			.build();
 		// authorization_code
 		// @formatter:off
@@ -222,22 +194,6 @@ public class ReactiveOAuth2AuthorizedClientProviderBuilderTests {
 		recordedRequest = this.server.takeRequest();
 		formParameters = recordedRequest.getBody().readUtf8();
 		assertThat(formParameters).contains("grant_type=client_credentials");
-		// password
-		// @formatter:off
-		OAuth2AuthorizationContext passwordContext = OAuth2AuthorizationContext
-				.withClientRegistration(
-						this.clientRegistrationBuilder.authorizationGrantType(AuthorizationGrantType.PASSWORD).build())
-				.principal(this.principal)
-				.attribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, "username")
-				.attribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, "password")
-				.build();
-		// @formatter:on
-		authorizedClient = authorizedClientProvider.authorize(passwordContext).block();
-		assertThat(authorizedClient).isNotNull();
-		assertThat(this.server.getRequestCount()).isEqualTo(3);
-		recordedRequest = this.server.takeRequest();
-		formParameters = recordedRequest.getBody().readUtf8();
-		assertThat(formParameters).contains("grant_type=password");
 	}
 
 	@Test

+ 1 - 25
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/DefaultOAuth2TokenRequestParametersConverterTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -149,30 +149,6 @@ public class DefaultOAuth2TokenRequestParametersConverterTests {
 			.containsExactly(StringUtils.collectionToDelimitedString(clientRegistration.getScopes(), " "));
 	}
 
-	@Test
-	public void convertWhenGrantRequestIsPasswordThenParametersProvided() {
-		ClientRegistration clientRegistration = this.clientRegistration
-			.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-			.build();
-		OAuth2PasswordGrantRequest grantRequest = new OAuth2PasswordGrantRequest(clientRegistration, "user",
-				"password");
-		// @formatter:off
-		DefaultOAuth2TokenRequestParametersConverter<OAuth2PasswordGrantRequest> parametersConverter =
-			new DefaultOAuth2TokenRequestParametersConverter<>();
-		// @formatter:on
-		MultiValueMap<String, String> parameters = parametersConverter.convert(grantRequest);
-		assertThat(parameters).hasSize(6);
-		assertThat(parameters.get(OAuth2ParameterNames.GRANT_TYPE))
-			.containsExactly(AuthorizationGrantType.PASSWORD.getValue());
-		assertThat(parameters.get(OAuth2ParameterNames.CLIENT_ID)).containsExactly(clientRegistration.getClientId());
-		assertThat(parameters.get(OAuth2ParameterNames.CLIENT_SECRET))
-			.containsExactly(clientRegistration.getClientSecret());
-		assertThat(parameters.get(OAuth2ParameterNames.USERNAME)).containsExactly(grantRequest.getUsername());
-		assertThat(parameters.get(OAuth2ParameterNames.PASSWORD)).containsExactly(grantRequest.getPassword());
-		assertThat(parameters.get(OAuth2ParameterNames.SCOPE))
-			.containsExactly(StringUtils.collectionToDelimitedString(clientRegistration.getScopes(), " "));
-	}
-
 	@Test
 	public void convertWhenGrantRequestIsJwtBearerThenParametersProvided() {
 		ClientRegistration clientRegistration = this.clientRegistration

+ 0 - 317
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/DefaultPasswordTokenResponseClientTests.java

@@ -1,317 +0,0 @@
-/*
- * Copyright 2002-2025 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.endpoint;
-
-import java.nio.charset.StandardCharsets;
-import java.time.Instant;
-import java.util.function.Function;
-
-import javax.crypto.spec.SecretKeySpec;
-
-import com.nimbusds.jose.jwk.JWK;
-import okhttp3.mockwebserver.MockResponse;
-import okhttp3.mockwebserver.MockWebServer;
-import okhttp3.mockwebserver.RecordedRequest;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.MediaType;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
-import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
-import org.springframework.security.oauth2.core.OAuth2AccessToken;
-import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
-import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.security.oauth2.jose.TestJwks;
-import org.springframework.security.oauth2.jose.TestKeys;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-
-/**
- * Tests for {@link DefaultPasswordTokenResponseClient}.
- *
- * @author Joe Grandja
- */
-public class DefaultPasswordTokenResponseClientTests {
-
-	private DefaultPasswordTokenResponseClient tokenResponseClient;
-
-	private ClientRegistration.Builder clientRegistration;
-
-	private String username = "user1";
-
-	private String password = "password";
-
-	private MockWebServer server;
-
-	@BeforeEach
-	public void setup() throws Exception {
-		this.tokenResponseClient = new DefaultPasswordTokenResponseClient();
-		this.server = new MockWebServer();
-		this.server.start();
-		String tokenUri = this.server.url("/oauth2/token").toString();
-		// @formatter:off
-		this.clientRegistration = TestClientRegistrations.password()
-				.scope("read", "write")
-				.tokenUri(tokenUri);
-		// @formatter:on
-	}
-
-	@AfterEach
-	public void cleanup() throws Exception {
-		this.server.shutdown();
-	}
-
-	@Test
-	public void setRequestEntityConverterWhenConverterIsNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.tokenResponseClient.setRequestEntityConverter(null));
-	}
-
-	@Test
-	public void setRestOperationsWhenRestOperationsIsNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.tokenResponseClient.setRestOperations(null));
-	}
-
-	@Test
-	public void getTokenResponseWhenRequestIsNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.tokenResponseClient.getTokenResponse(null));
-	}
-
-	@Test
-	public void getTokenResponseWhenSuccessResponseThenReturnAccessTokenResponse() throws Exception {
-		// @formatter:off
-		String accessTokenSuccessResponse = "{\n"
-			+ "   \"access_token\": \"access-token-1234\",\n"
-			+ "   \"token_type\": \"bearer\",\n"
-			+ "   \"expires_in\": \"3600\",\n"
-			+ "   \"scope\": \"read write\"\n"
-			+ "}\n";
-		// @formatter:on
-		this.server.enqueue(jsonResponse(accessTokenSuccessResponse));
-		Instant expiresAtBefore = Instant.now().plusSeconds(3600);
-		ClientRegistration clientRegistration = this.clientRegistration.build();
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration,
-				this.username, this.password);
-		OAuth2AccessTokenResponse accessTokenResponse = this.tokenResponseClient.getTokenResponse(passwordGrantRequest);
-		Instant expiresAtAfter = Instant.now().plusSeconds(3600);
-		RecordedRequest recordedRequest = this.server.takeRequest();
-		assertThat(recordedRequest.getMethod()).isEqualTo(HttpMethod.POST.toString());
-		assertThat(recordedRequest.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.APPLICATION_JSON_VALUE);
-		assertThat(recordedRequest.getHeader(HttpHeaders.CONTENT_TYPE))
-			.isEqualTo(MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8");
-		String formParameters = recordedRequest.getBody().readUtf8();
-		assertThat(formParameters).contains("grant_type=password");
-		assertThat(formParameters).contains("username=user1");
-		assertThat(formParameters).contains("password=password");
-		assertThat(formParameters).contains("scope=read+write");
-		assertThat(accessTokenResponse.getAccessToken().getTokenValue()).isEqualTo("access-token-1234");
-		assertThat(accessTokenResponse.getAccessToken().getTokenType()).isEqualTo(OAuth2AccessToken.TokenType.BEARER);
-		assertThat(accessTokenResponse.getAccessToken().getExpiresAt()).isBetween(expiresAtBefore, expiresAtAfter);
-		assertThat(accessTokenResponse.getAccessToken().getScopes())
-			.containsExactly(clientRegistration.getScopes().toArray(new String[0]));
-		assertThat(accessTokenResponse.getRefreshToken()).isNull();
-	}
-
-	@Test
-	public void getTokenResponseWhenAuthenticationClientSecretPostThenFormParametersAreSent() throws Exception {
-		// @formatter:off
-		String accessTokenSuccessResponse = "{\n"
-			+ "   \"access_token\": \"access-token-1234\",\n"
-			+ "   \"token_type\": \"bearer\",\n"
-			+ "   \"expires_in\": \"3600\",\n"
-			+ "   \"scope\": \"read\"\n"
-			+ "}\n";
-		// @formatter:on
-		this.server.enqueue(jsonResponse(accessTokenSuccessResponse));
-		ClientRegistration clientRegistration = this.clientRegistration
-			.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
-			.build();
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration,
-				this.username, this.password);
-		this.tokenResponseClient.getTokenResponse(passwordGrantRequest);
-		RecordedRequest recordedRequest = this.server.takeRequest();
-		assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull();
-		String formParameters = recordedRequest.getBody().readUtf8();
-		assertThat(formParameters).contains("client_id=client-id");
-		assertThat(formParameters).contains("client_secret=client-secret");
-	}
-
-	@Test
-	public void getTokenResponseWhenAuthenticationClientSecretJwtThenFormParametersAreSent() throws Exception {
-		// @formatter:off
-		String accessTokenSuccessResponse = "{\n"
-				+ "	\"access_token\": \"access-token-1234\",\n"
-				+ "   \"token_type\": \"bearer\",\n"
-				+ "   \"expires_in\": \"3600\"\n"
-				+ "}\n";
-		// @formatter:on
-		this.server.enqueue(jsonResponse(accessTokenSuccessResponse));
-
-		// @formatter:off
-		ClientRegistration clientRegistration = this.clientRegistration
-				.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_JWT)
-				.clientSecret(TestKeys.DEFAULT_ENCODED_SECRET_KEY)
-				.build();
-		// @formatter:on
-
-		// Configure Jwt client authentication converter
-		SecretKeySpec secretKey = new SecretKeySpec(
-				clientRegistration.getClientSecret().getBytes(StandardCharsets.UTF_8), "HmacSHA256");
-		JWK jwk = TestJwks.jwk(secretKey).build();
-		Function<ClientRegistration, JWK> jwkResolver = (registration) -> jwk;
-		configureJwtClientAuthenticationConverter(jwkResolver);
-
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration,
-				this.username, this.password);
-		this.tokenResponseClient.getTokenResponse(passwordGrantRequest);
-		RecordedRequest recordedRequest = this.server.takeRequest();
-		assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull();
-		String formParameters = recordedRequest.getBody().readUtf8();
-		assertThat(formParameters)
-			.contains("client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer");
-		assertThat(formParameters).contains("client_assertion=");
-	}
-
-	@Test
-	public void getTokenResponseWhenAuthenticationPrivateKeyJwtThenFormParametersAreSent() throws Exception {
-		// @formatter:off
-		String accessTokenSuccessResponse = "{\n"
-				+ "	\"access_token\": \"access-token-1234\",\n"
-				+ "   \"token_type\": \"bearer\",\n"
-				+ "   \"expires_in\": \"3600\"\n"
-				+ "}\n";
-		// @formatter:on
-		this.server.enqueue(jsonResponse(accessTokenSuccessResponse));
-
-		// @formatter:off
-		ClientRegistration clientRegistration = this.clientRegistration
-				.clientAuthenticationMethod(ClientAuthenticationMethod.PRIVATE_KEY_JWT)
-				.build();
-		// @formatter:on
-
-		// Configure Jwt client authentication converter
-		JWK jwk = TestJwks.DEFAULT_RSA_JWK;
-		Function<ClientRegistration, JWK> jwkResolver = (registration) -> jwk;
-		configureJwtClientAuthenticationConverter(jwkResolver);
-
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration,
-				this.username, this.password);
-		this.tokenResponseClient.getTokenResponse(passwordGrantRequest);
-		RecordedRequest recordedRequest = this.server.takeRequest();
-		assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull();
-		String formParameters = recordedRequest.getBody().readUtf8();
-		assertThat(formParameters)
-			.contains("client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer");
-		assertThat(formParameters).contains("client_assertion=");
-	}
-
-	private void configureJwtClientAuthenticationConverter(Function<ClientRegistration, JWK> jwkResolver) {
-		NimbusJwtClientAuthenticationParametersConverter<OAuth2PasswordGrantRequest> jwtClientAuthenticationConverter = new NimbusJwtClientAuthenticationParametersConverter<>(
-				jwkResolver);
-		OAuth2PasswordGrantRequestEntityConverter requestEntityConverter = new OAuth2PasswordGrantRequestEntityConverter();
-		requestEntityConverter.addParametersConverter(jwtClientAuthenticationConverter);
-		this.tokenResponseClient.setRequestEntityConverter(requestEntityConverter);
-	}
-
-	@Test
-	public void getTokenResponseWhenSuccessResponseAndNotBearerTokenTypeThenThrowOAuth2AuthorizationException() {
-		// @formatter:off
-		String accessTokenSuccessResponse = "{\n"
-			+ "   \"access_token\": \"access-token-1234\",\n"
-			+ "   \"token_type\": \"not-bearer\",\n"
-			+ "   \"expires_in\": \"3600\"\n"
-			+ "}\n";
-		// @formatter:on
-		this.server.enqueue(jsonResponse(accessTokenSuccessResponse));
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(
-				this.clientRegistration.build(), this.username, this.password);
-		assertThatExceptionOfType(OAuth2AuthorizationException.class)
-			.isThrownBy(() -> this.tokenResponseClient.getTokenResponse(passwordGrantRequest))
-			.withMessageContaining(
-					"[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response")
-			.havingRootCause()
-			.withMessageContaining("tokenType cannot be null");
-	}
-
-	@Test
-	public void getTokenResponseWhenSuccessResponseIncludesScopeThenAccessTokenHasResponseScope() throws Exception {
-		// @formatter:off
-		String accessTokenSuccessResponse = "{\n"
-			+ "   \"access_token\": \"access-token-1234\",\n"
-			+ "   \"token_type\": \"bearer\",\n"
-			+ "   \"expires_in\": \"3600\",\n"
-			+ "   \"scope\": \"read\"\n"
-			+ "}\n";
-		// @formatter:on
-		this.server.enqueue(jsonResponse(accessTokenSuccessResponse));
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(
-				this.clientRegistration.build(), this.username, this.password);
-		OAuth2AccessTokenResponse accessTokenResponse = this.tokenResponseClient.getTokenResponse(passwordGrantRequest);
-		RecordedRequest recordedRequest = this.server.takeRequest();
-		String formParameters = recordedRequest.getBody().readUtf8();
-		assertThat(formParameters).contains("scope=read");
-		assertThat(accessTokenResponse.getAccessToken().getScopes()).containsExactly("read");
-	}
-
-	@Test
-	public void getTokenResponseWhenSuccessResponseDoesNotIncludeScopeThenAccessTokenHasNoScope() {
-		// @formatter:off
-		String accessTokenSuccessResponse = "{\n"
-			+ "   \"access_token\": \"access-token-1234\",\n"
-			+ "   \"token_type\": \"bearer\",\n"
-			+ "   \"expires_in\": \"3600\"\n"
-			+ "}\n";
-		// @formatter:on
-		this.server.enqueue(jsonResponse(accessTokenSuccessResponse));
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(
-				this.clientRegistration.build(), this.username, this.password);
-		OAuth2AccessTokenResponse accessTokenResponse = this.tokenResponseClient.getTokenResponse(passwordGrantRequest);
-		assertThat(accessTokenResponse.getAccessToken().getScopes()).isEmpty();
-	}
-
-	@Test
-	public void getTokenResponseWhenErrorResponseThenThrowOAuth2AuthorizationException() {
-		String accessTokenErrorResponse = "{\n" + "   \"error\": \"unauthorized_client\"\n" + "}\n";
-		this.server.enqueue(jsonResponse(accessTokenErrorResponse).setResponseCode(400));
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(
-				this.clientRegistration.build(), this.username, this.password);
-		assertThatExceptionOfType(OAuth2AuthorizationException.class)
-			.isThrownBy(() -> this.tokenResponseClient.getTokenResponse(passwordGrantRequest))
-			.withMessageContaining("[unauthorized_client]");
-	}
-
-	@Test
-	public void getTokenResponseWhenServerErrorResponseThenThrowOAuth2AuthorizationException() {
-		this.server.enqueue(new MockResponse().setResponseCode(500));
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(
-				this.clientRegistration.build(), this.username, this.password);
-		assertThatExceptionOfType(OAuth2AuthorizationException.class)
-			.isThrownBy(() -> this.tokenResponseClient.getTokenResponse(passwordGrantRequest))
-			.withMessageContaining("[invalid_token_response] An error occurred while attempting to "
-					+ "retrieve the OAuth 2.0 Access Token Response");
-	}
-
-	private MockResponse jsonResponse(String json) {
-		return new MockResponse().setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).setBody(json);
-	}
-
-}

+ 0 - 133
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/OAuth2PasswordGrantRequestEntityConverterTests.java

@@ -1,133 +0,0 @@
-/*
- * Copyright 2002-2025 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.endpoint;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.InOrder;
-
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.MediaType;
-import org.springframework.http.RequestEntity;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
-import org.springframework.security.oauth2.core.AuthorizationGrantType;
-import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
-import org.springframework.util.MultiValueMap;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-
-/**
- * Tests for {@link OAuth2PasswordGrantRequestEntityConverter}.
- *
- * @author Joe Grandja
- */
-public class OAuth2PasswordGrantRequestEntityConverterTests {
-
-	private OAuth2PasswordGrantRequestEntityConverter converter;
-
-	@BeforeEach
-	public void setup() {
-		this.converter = new OAuth2PasswordGrantRequestEntityConverter();
-	}
-
-	@Test
-	public void setHeadersConverterWhenNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.converter.setHeadersConverter(null))
-			.withMessage("headersConverter cannot be null");
-	}
-
-	@Test
-	public void addHeadersConverterWhenNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.converter.addHeadersConverter(null))
-			.withMessage("headersConverter cannot be null");
-	}
-
-	@Test
-	public void setParametersConverterWhenNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.converter.setParametersConverter(null))
-			.withMessage("parametersConverter cannot be null");
-	}
-
-	@Test
-	public void addParametersConverterWhenNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.converter.addParametersConverter(null))
-			.withMessage("parametersConverter cannot be null");
-	}
-
-	@Test
-	public void convertWhenHeadersConverterSetThenCalled() {
-		Converter<OAuth2PasswordGrantRequest, HttpHeaders> headersConverter1 = mock(Converter.class);
-		this.converter.setHeadersConverter(headersConverter1);
-		Converter<OAuth2PasswordGrantRequest, HttpHeaders> headersConverter2 = mock(Converter.class);
-		this.converter.addHeadersConverter(headersConverter2);
-		ClientRegistration clientRegistration = TestClientRegistrations.password().build();
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration, "user1",
-				"password");
-		this.converter.convert(passwordGrantRequest);
-		InOrder inOrder = inOrder(headersConverter1, headersConverter2);
-		inOrder.verify(headersConverter1).convert(any(OAuth2PasswordGrantRequest.class));
-		inOrder.verify(headersConverter2).convert(any(OAuth2PasswordGrantRequest.class));
-	}
-
-	@Test
-	public void convertWhenParametersConverterSetThenCalled() {
-		Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>> parametersConverter1 = mock(
-				Converter.class);
-		this.converter.setParametersConverter(parametersConverter1);
-		Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>> parametersConverter2 = mock(
-				Converter.class);
-		this.converter.addParametersConverter(parametersConverter2);
-		ClientRegistration clientRegistration = TestClientRegistrations.password().build();
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration, "user1",
-				"password");
-		this.converter.convert(passwordGrantRequest);
-		InOrder inOrder = inOrder(parametersConverter1, parametersConverter2);
-		inOrder.verify(parametersConverter1).convert(any(OAuth2PasswordGrantRequest.class));
-		inOrder.verify(parametersConverter2).convert(any(OAuth2PasswordGrantRequest.class));
-	}
-
-	@SuppressWarnings("unchecked")
-	@Test
-	public void convertWhenGrantRequestValidThenConverts() {
-		ClientRegistration clientRegistration = TestClientRegistrations.password().build();
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration, "user1",
-				"password");
-		RequestEntity<?> requestEntity = this.converter.convert(passwordGrantRequest);
-		assertThat(requestEntity.getMethod()).isEqualTo(HttpMethod.POST);
-		assertThat(requestEntity.getUrl().toASCIIString())
-			.isEqualTo(clientRegistration.getProviderDetails().getTokenUri());
-		HttpHeaders headers = requestEntity.getHeaders();
-		assertThat(headers.getAccept()).contains(MediaType.APPLICATION_JSON);
-		assertThat(headers.getContentType())
-			.isEqualTo(MediaType.valueOf(MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8"));
-		assertThat(headers.getFirst(HttpHeaders.AUTHORIZATION)).startsWith("Basic ");
-		MultiValueMap<String, String> formParameters = (MultiValueMap<String, String>) requestEntity.getBody();
-		assertThat(formParameters.getFirst(OAuth2ParameterNames.GRANT_TYPE))
-			.isEqualTo(AuthorizationGrantType.PASSWORD.getValue());
-		assertThat(formParameters.getFirst(OAuth2ParameterNames.USERNAME)).isEqualTo("user1");
-		assertThat(formParameters.getFirst(OAuth2ParameterNames.PASSWORD)).isEqualTo("password");
-		assertThat(formParameters.getFirst(OAuth2ParameterNames.SCOPE)).contains(clientRegistration.getScopes());
-	}
-
-}

+ 0 - 88
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/OAuth2PasswordGrantRequestTests.java

@@ -1,88 +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.endpoint;
-
-import org.junit.jupiter.api.Test;
-
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
-import org.springframework.security.oauth2.core.AuthorizationGrantType;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-
-/**
- * Tests for {@link OAuth2PasswordGrantRequest}.
- *
- * @author Joe Grandja
- */
-public class OAuth2PasswordGrantRequestTests {
-
-	private ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration()
-		.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-		.build();
-
-	private String username = "user1";
-
-	private String password = "password";
-
-	@Test
-	public void constructorWhenClientRegistrationIsNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException()
-			.isThrownBy(() -> new OAuth2PasswordGrantRequest(null, this.username, this.password))
-			.withMessage("clientRegistration cannot be null");
-	}
-
-	@Test
-	public void constructorWhenUsernameIsEmptyThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException()
-			.isThrownBy(() -> new OAuth2PasswordGrantRequest(this.clientRegistration, null, this.password))
-			.withMessage("username cannot be empty");
-		assertThatIllegalArgumentException()
-			.isThrownBy(() -> new OAuth2PasswordGrantRequest(this.clientRegistration, "", this.password))
-			.withMessage("username cannot be empty");
-	}
-
-	@Test
-	public void constructorWhenPasswordIsEmptyThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException()
-			.isThrownBy(() -> new OAuth2PasswordGrantRequest(this.clientRegistration, this.username, null))
-			.withMessage("password cannot be empty");
-		assertThatIllegalArgumentException()
-			.isThrownBy(() -> new OAuth2PasswordGrantRequest(this.clientRegistration, this.username, ""))
-			.withMessage("password cannot be empty");
-	}
-
-	@Test
-	public void constructorWhenClientRegistrationInvalidGrantTypeThenThrowIllegalArgumentException() {
-		ClientRegistration registration = TestClientRegistrations.clientCredentials().build();
-		assertThatIllegalArgumentException()
-			.isThrownBy(() -> new OAuth2PasswordGrantRequest(registration, this.username, this.password))
-			.withMessage("clientRegistration.authorizationGrantType must be AuthorizationGrantType.PASSWORD");
-	}
-
-	@Test
-	public void constructorWhenValidParametersProvidedThenCreated() {
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(this.clientRegistration,
-				this.username, this.password);
-		assertThat(passwordGrantRequest.getGrantType()).isEqualTo(AuthorizationGrantType.PASSWORD);
-		assertThat(passwordGrantRequest.getClientRegistration()).isSameAs(this.clientRegistration);
-		assertThat(passwordGrantRequest.getUsername()).isEqualTo(this.username);
-		assertThat(passwordGrantRequest.getPassword()).isEqualTo(this.password);
-	}
-
-}

+ 0 - 450
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactivePasswordTokenResponseClientTests.java

@@ -1,450 +0,0 @@
-/*
- * Copyright 2002-2024 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.endpoint;
-
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import java.time.Instant;
-import java.util.Collections;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-import javax.crypto.spec.SecretKeySpec;
-
-import com.nimbusds.jose.jwk.JWK;
-import okhttp3.mockwebserver.MockResponse;
-import okhttp3.mockwebserver.MockWebServer;
-import okhttp3.mockwebserver.RecordedRequest;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import reactor.core.publisher.Mono;
-
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.MediaType;
-import org.springframework.http.ReactiveHttpInputMessage;
-import org.springframework.security.oauth2.client.MockResponses;
-import org.springframework.security.oauth2.client.registration.ClientRegistration;
-import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
-import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
-import org.springframework.security.oauth2.core.OAuth2AccessToken;
-import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
-import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
-import org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses;
-import org.springframework.security.oauth2.jose.TestJwks;
-import org.springframework.security.oauth2.jose.TestKeys;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.reactive.function.BodyExtractor;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-/**
- * Tests for {@link WebClientReactivePasswordTokenResponseClient}.
- *
- * @author Joe Grandja
- */
-public class WebClientReactivePasswordTokenResponseClientTests {
-
-	private WebClientReactivePasswordTokenResponseClient tokenResponseClient = new WebClientReactivePasswordTokenResponseClient();
-
-	private ClientRegistration.Builder clientRegistrationBuilder;
-
-	private String username = "user1";
-
-	private String password = "password";
-
-	private MockWebServer server;
-
-	@BeforeEach
-	public void setup() throws Exception {
-		this.server = new MockWebServer();
-		this.server.start();
-		String tokenUri = this.server.url("/oauth2/token").toString();
-		this.clientRegistrationBuilder = TestClientRegistrations.password().tokenUri(tokenUri);
-	}
-
-	@AfterEach
-	public void cleanup() throws Exception {
-		this.server.shutdown();
-	}
-
-	@Test
-	public void setWebClientWhenClientIsNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.tokenResponseClient.setWebClient(null));
-	}
-
-	@Test
-	public void getTokenResponseWhenRequestIsNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.tokenResponseClient.getTokenResponse(null).block());
-	}
-
-	@Test
-	public void getTokenResponseWhenSuccessResponseDoesNotIncludeScopeThenReturnAccessTokenResponseWithNoScope()
-			throws Exception {
-		this.server.enqueue(MockResponses.json("access-token-response.json"));
-		Instant expiresAtBefore = Instant.now().plusSeconds(3600);
-		ClientRegistration clientRegistration = this.clientRegistrationBuilder.build();
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration,
-				this.username, this.password);
-		OAuth2AccessTokenResponse accessTokenResponse = this.tokenResponseClient.getTokenResponse(passwordGrantRequest)
-			.block();
-		Instant expiresAtAfter = Instant.now().plusSeconds(3600);
-		RecordedRequest recordedRequest = this.server.takeRequest();
-		assertThat(recordedRequest.getMethod()).isEqualTo(HttpMethod.POST.toString());
-		assertThat(recordedRequest.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.APPLICATION_JSON_VALUE);
-		assertThat(recordedRequest.getHeader(HttpHeaders.CONTENT_TYPE))
-			.isEqualTo(MediaType.APPLICATION_FORM_URLENCODED_VALUE);
-		String formParameters = recordedRequest.getBody().readUtf8();
-		assertThat(formParameters).contains("grant_type=password");
-		assertThat(formParameters).contains("username=user1");
-		assertThat(formParameters).contains("password=password");
-		assertThat(formParameters).contains("scope=read+write");
-		assertThat(accessTokenResponse.getAccessToken().getTokenValue()).isEqualTo("access-token-1234");
-		assertThat(accessTokenResponse.getAccessToken().getTokenType()).isEqualTo(OAuth2AccessToken.TokenType.BEARER);
-		assertThat(accessTokenResponse.getAccessToken().getExpiresAt()).isBetween(expiresAtBefore, expiresAtAfter);
-		assertThat(accessTokenResponse.getAccessToken().getScopes()).isEmpty();
-		assertThat(accessTokenResponse.getRefreshToken()).isNull();
-	}
-
-	@Test
-	public void getTokenResponseWhenSuccessResponseIncludesScopeThenReturnAccessTokenResponse() throws Exception {
-		this.server.enqueue(MockResponses.json("access-token-response-read-write.json"));
-		Instant expiresAtBefore = Instant.now().plusSeconds(3600);
-		ClientRegistration clientRegistration = this.clientRegistrationBuilder.build();
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration,
-				this.username, this.password);
-		OAuth2AccessTokenResponse accessTokenResponse = this.tokenResponseClient.getTokenResponse(passwordGrantRequest)
-			.block();
-		Instant expiresAtAfter = Instant.now().plusSeconds(3600);
-		RecordedRequest recordedRequest = this.server.takeRequest();
-		assertThat(recordedRequest.getMethod()).isEqualTo(HttpMethod.POST.toString());
-		assertThat(recordedRequest.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.APPLICATION_JSON_VALUE);
-		assertThat(recordedRequest.getHeader(HttpHeaders.CONTENT_TYPE))
-			.isEqualTo(MediaType.APPLICATION_FORM_URLENCODED_VALUE);
-		String formParameters = recordedRequest.getBody().readUtf8();
-		assertThat(formParameters).contains("grant_type=password");
-		assertThat(formParameters).contains("username=user1");
-		assertThat(formParameters).contains("password=password");
-		assertThat(formParameters).contains("scope=read+write");
-		assertThat(accessTokenResponse.getAccessToken().getTokenValue()).isEqualTo("access-token-1234");
-		assertThat(accessTokenResponse.getAccessToken().getTokenType()).isEqualTo(OAuth2AccessToken.TokenType.BEARER);
-		assertThat(accessTokenResponse.getAccessToken().getExpiresAt()).isBetween(expiresAtBefore, expiresAtAfter);
-		assertThat(accessTokenResponse.getAccessToken().getScopes())
-			.containsExactly(clientRegistration.getScopes().toArray(new String[0]));
-		assertThat(accessTokenResponse.getRefreshToken()).isNull();
-	}
-
-	@Test
-	public void getTokenResponseWhenClientAuthenticationPostThenFormParametersAreSent() throws Exception {
-		this.server.enqueue(MockResponses.json("access-token-response.json"));
-		ClientRegistration clientRegistration = this.clientRegistrationBuilder
-			.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
-			.build();
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration,
-				this.username, this.password);
-		this.tokenResponseClient.getTokenResponse(passwordGrantRequest).block();
-		RecordedRequest recordedRequest = this.server.takeRequest();
-		assertThat(recordedRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull();
-		String formParameters = recordedRequest.getBody().readUtf8();
-		assertThat(formParameters).contains("client_id=client-id");
-		assertThat(formParameters).contains("client_secret=client-secret");
-	}
-
-	@Test
-	public void getTokenResponseWhenAuthenticationClientSecretJwtThenFormParametersAreSent() throws Exception {
-		this.server.enqueue(MockResponses.json("access-token-response.json"));
-
-		// @formatter:off
-		ClientRegistration clientRegistration = this.clientRegistrationBuilder
-				.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_JWT)
-				.clientSecret(TestKeys.DEFAULT_ENCODED_SECRET_KEY)
-				.build();
-		// @formatter:on
-
-		// Configure Jwt client authentication converter
-		SecretKeySpec secretKey = new SecretKeySpec(
-				clientRegistration.getClientSecret().getBytes(StandardCharsets.UTF_8), "HmacSHA256");
-		JWK jwk = TestJwks.jwk(secretKey).build();
-		Function<ClientRegistration, JWK> jwkResolver = (registration) -> jwk;
-		configureJwtClientAuthenticationConverter(jwkResolver);
-
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration,
-				this.username, this.password);
-		this.tokenResponseClient.getTokenResponse(passwordGrantRequest).block();
-		RecordedRequest actualRequest = this.server.takeRequest();
-		assertThat(actualRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull();
-		assertThat(actualRequest.getBody().readUtf8()).contains("grant_type=password",
-				"client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer",
-				"client_assertion=");
-	}
-
-	@Test
-	public void getTokenResponseWhenAuthenticationPrivateKeyJwtThenFormParametersAreSent() throws Exception {
-		this.server.enqueue(MockResponses.json("access-token-response.json"));
-
-		// @formatter:off
-		ClientRegistration clientRegistration = this.clientRegistrationBuilder
-				.clientAuthenticationMethod(ClientAuthenticationMethod.PRIVATE_KEY_JWT)
-				.build();
-		// @formatter:on
-
-		// Configure Jwt client authentication converter
-		JWK jwk = TestJwks.DEFAULT_RSA_JWK;
-		Function<ClientRegistration, JWK> jwkResolver = (registration) -> jwk;
-		configureJwtClientAuthenticationConverter(jwkResolver);
-
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration,
-				this.username, this.password);
-		this.tokenResponseClient.getTokenResponse(passwordGrantRequest).block();
-		RecordedRequest actualRequest = this.server.takeRequest();
-		assertThat(actualRequest.getHeader(HttpHeaders.AUTHORIZATION)).isNull();
-		assertThat(actualRequest.getBody().readUtf8()).contains("grant_type=password",
-				"client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer",
-				"client_assertion=");
-	}
-
-	private void configureJwtClientAuthenticationConverter(Function<ClientRegistration, JWK> jwkResolver) {
-		NimbusJwtClientAuthenticationParametersConverter<OAuth2PasswordGrantRequest> jwtClientAuthenticationConverter = new NimbusJwtClientAuthenticationParametersConverter<>(
-				jwkResolver);
-		this.tokenResponseClient.addParametersConverter(jwtClientAuthenticationConverter);
-	}
-
-	@Test
-	public void getTokenResponseWhenSuccessResponseAndNotBearerTokenTypeThenThrowOAuth2AuthorizationException() {
-		this.server.enqueue(MockResponses.json("invalid-token-type-response.json"));
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(
-				this.clientRegistrationBuilder.build(), this.username, this.password);
-		assertThatExceptionOfType(OAuth2AuthorizationException.class)
-			.isThrownBy(() -> this.tokenResponseClient.getTokenResponse(passwordGrantRequest).block())
-			.satisfies((ex) -> assertThat(ex.getError().getErrorCode()).isEqualTo("invalid_token_response"))
-			.withMessageContaining("[invalid_token_response]")
-			.withMessageContaining("An error occurred parsing the Access Token response")
-			.withCauseInstanceOf(Throwable.class);
-	}
-
-	@Test
-	public void getTokenResponseWhenSuccessResponseIncludesScopeThenAccessTokenHasResponseScope() throws Exception {
-		this.server.enqueue(MockResponses.json("access-token-response-read.json"));
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(
-				this.clientRegistrationBuilder.build(), this.username, this.password);
-		OAuth2AccessTokenResponse accessTokenResponse = this.tokenResponseClient.getTokenResponse(passwordGrantRequest)
-			.block();
-		RecordedRequest recordedRequest = this.server.takeRequest();
-		String formParameters = recordedRequest.getBody().readUtf8();
-		assertThat(formParameters).contains("scope=read");
-		assertThat(accessTokenResponse.getAccessToken().getScopes()).containsExactly("read");
-	}
-
-	@Test
-	public void getTokenResponseWhenErrorResponseThenThrowOAuth2AuthorizationException() {
-		this.server.enqueue(MockResponses.json("unauthorized-client-response.json").setResponseCode(400));
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(
-				this.clientRegistrationBuilder.build(), this.username, this.password);
-		assertThatExceptionOfType(OAuth2AuthorizationException.class)
-			.isThrownBy(() -> this.tokenResponseClient.getTokenResponse(passwordGrantRequest).block())
-			.satisfies((ex) -> assertThat(ex.getError().getErrorCode()).isEqualTo("unauthorized_client"))
-			.withMessageContaining("[unauthorized_client]");
-	}
-
-	@Test
-	public void getTokenResponseWhenServerErrorResponseThenThrowOAuth2AuthorizationException() {
-		this.server.enqueue(new MockResponse().setResponseCode(500));
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(
-				this.clientRegistrationBuilder.build(), this.username, this.password);
-		assertThatExceptionOfType(OAuth2AuthorizationException.class)
-			.isThrownBy(() -> this.tokenResponseClient.getTokenResponse(passwordGrantRequest).block())
-			.satisfies((ex) -> assertThat(ex.getError().getErrorCode()).isEqualTo("invalid_token_response"))
-			.withMessageContaining("[invalid_token_response]")
-			.withMessageContaining("Empty OAuth 2.0 Access Token Response");
-	}
-
-	// gh-10130
-	@Test
-	public void setHeadersConverterWhenNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.tokenResponseClient.setHeadersConverter(null))
-			.withMessage("headersConverter cannot be null");
-	}
-
-	// gh-10130
-	@Test
-	public void addHeadersConverterWhenNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.tokenResponseClient.addHeadersConverter(null))
-			.withMessage("headersConverter cannot be null");
-	}
-
-	// gh-10130
-	@Test
-	public void convertWhenHeadersConverterAddedThenCalled() throws Exception {
-		OAuth2PasswordGrantRequest request = new OAuth2PasswordGrantRequest(this.clientRegistrationBuilder.build(),
-				this.username, this.password);
-		Converter<OAuth2PasswordGrantRequest, HttpHeaders> addedHeadersConverter = mock();
-		HttpHeaders headers = new HttpHeaders();
-		headers.put("custom-header-name", Collections.singletonList("custom-header-value"));
-		given(addedHeadersConverter.convert(request)).willReturn(headers);
-		this.tokenResponseClient.addHeadersConverter(addedHeadersConverter);
-		this.server.enqueue(MockResponses.json("access-token-response.json"));
-		this.tokenResponseClient.getTokenResponse(request).block();
-		verify(addedHeadersConverter).convert(request);
-		RecordedRequest actualRequest = this.server.takeRequest();
-		assertThat(actualRequest.getHeader(HttpHeaders.AUTHORIZATION))
-			.isEqualTo("Basic Y2xpZW50LWlkOmNsaWVudC1zZWNyZXQ=");
-		assertThat(actualRequest.getHeader("custom-header-name")).isEqualTo("custom-header-value");
-	}
-
-	// gh-10130
-	@Test
-	public void convertWhenHeadersConverterSetThenCalled() throws Exception {
-		OAuth2PasswordGrantRequest request = new OAuth2PasswordGrantRequest(this.clientRegistrationBuilder.build(),
-				this.username, this.password);
-		ClientRegistration clientRegistration = request.getClientRegistration();
-		Converter<OAuth2PasswordGrantRequest, HttpHeaders> headersConverter = mock();
-		HttpHeaders headers = new HttpHeaders();
-		headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret());
-		given(headersConverter.convert(request)).willReturn(headers);
-		this.tokenResponseClient.setHeadersConverter(headersConverter);
-		this.server.enqueue(MockResponses.json("access-token-response.json"));
-		this.tokenResponseClient.getTokenResponse(request).block();
-		verify(headersConverter).convert(request);
-		RecordedRequest actualRequest = this.server.takeRequest();
-		assertThat(actualRequest.getHeader(HttpHeaders.AUTHORIZATION))
-			.isEqualTo("Basic Y2xpZW50LWlkOmNsaWVudC1zZWNyZXQ=");
-	}
-
-	@Test
-	public void setParametersConverterWhenNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.tokenResponseClient.setParametersConverter(null))
-			.withMessage("parametersConverter cannot be null");
-	}
-
-	@Test
-	public void addParametersConverterWhenNullThenThrowIllegalArgumentException() {
-		assertThatIllegalArgumentException().isThrownBy(() -> this.tokenResponseClient.addParametersConverter(null))
-			.withMessage("parametersConverter cannot be null");
-	}
-
-	@Test
-	public void getTokenResponseWhenParametersConverterAddedThenCalled() throws Exception {
-		OAuth2PasswordGrantRequest request = new OAuth2PasswordGrantRequest(this.clientRegistrationBuilder.build(),
-				this.username, this.password);
-		Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>> addedParametersConverter = mock();
-		MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
-		parameters.add("custom-parameter-name", "custom-parameter-value");
-		given(addedParametersConverter.convert(request)).willReturn(parameters);
-		this.tokenResponseClient.addParametersConverter(addedParametersConverter);
-		this.server.enqueue(MockResponses.json("access-token-response.json"));
-		this.tokenResponseClient.getTokenResponse(request).block();
-		verify(addedParametersConverter).convert(request);
-		RecordedRequest actualRequest = this.server.takeRequest();
-		String formParameters = actualRequest.getBody().readUtf8();
-		// @formatter:off
-		assertThat(formParameters).contains(
-				param(OAuth2ParameterNames.GRANT_TYPE, "password"),
-				param("custom-parameter-name", "custom-parameter-value")
-		);
-		// @formatter:on
-	}
-
-	@Test
-	public void getTokenResponseWhenParametersConverterSetThenCalled() throws Exception {
-		OAuth2PasswordGrantRequest request = new OAuth2PasswordGrantRequest(this.clientRegistrationBuilder.build(),
-				this.username, this.password);
-		Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>> parametersConverter = mock();
-		MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
-		parameters.add("custom-parameter-name", "custom-parameter-value");
-		given(parametersConverter.convert(request)).willReturn(parameters);
-		this.tokenResponseClient.setParametersConverter(parametersConverter);
-		this.server.enqueue(MockResponses.json("access-token-response.json"));
-		this.tokenResponseClient.getTokenResponse(request).block();
-		verify(parametersConverter).convert(request);
-		RecordedRequest actualRequest = this.server.takeRequest();
-		assertThat(actualRequest.getBody().readUtf8()).contains("custom-parameter-name=custom-parameter-value");
-	}
-
-	@Test
-	public void getTokenResponseWhenParametersConverterSetThenAbleToOverrideDefaultParameters() throws Exception {
-		this.clientRegistrationBuilder.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST);
-		OAuth2PasswordGrantRequest request = new OAuth2PasswordGrantRequest(this.clientRegistrationBuilder.build(),
-				this.username, this.password);
-		MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
-		parameters.set(OAuth2ParameterNames.GRANT_TYPE, "custom");
-		parameters.set(OAuth2ParameterNames.USERNAME, "user");
-		parameters.set(OAuth2ParameterNames.PASSWORD, "password");
-		parameters.set(OAuth2ParameterNames.SCOPE, "one two");
-		this.tokenResponseClient.setParametersConverter((grantRequest) -> parameters);
-		this.server.enqueue(MockResponses.json("access-token-response.json"));
-		this.tokenResponseClient.getTokenResponse(request).block();
-		String formParameters = this.server.takeRequest().getBody().readUtf8();
-		// @formatter:off
-		assertThat(formParameters).contains(
-				param(OAuth2ParameterNames.GRANT_TYPE, "custom"),
-				param(OAuth2ParameterNames.CLIENT_ID, "client-id"),
-				param(OAuth2ParameterNames.SCOPE, "one two"),
-				param(OAuth2ParameterNames.USERNAME, "user"),
-				param(OAuth2ParameterNames.PASSWORD, "password")
-		);
-		// @formatter:on
-	}
-
-	@Test
-	public void getTokenResponseWhenParametersCustomizerSetThenCalled() throws Exception {
-		this.server.enqueue(MockResponses.json("access-token-response.json"));
-		OAuth2PasswordGrantRequest request = new OAuth2PasswordGrantRequest(this.clientRegistrationBuilder.build(),
-				this.username, this.password);
-		Consumer<MultiValueMap<String, String>> parametersCustomizer = mock();
-		this.tokenResponseClient.setParametersCustomizer(parametersCustomizer);
-		this.tokenResponseClient.getTokenResponse(request).block();
-		verify(parametersCustomizer).accept(any());
-	}
-
-	// gh-10260
-	@Test
-	public void getTokenResponseWhenSuccessCustomResponseThenReturnAccessTokenResponse() {
-
-		WebClientReactivePasswordTokenResponseClient customClient = new WebClientReactivePasswordTokenResponseClient();
-
-		BodyExtractor<Mono<OAuth2AccessTokenResponse>, ReactiveHttpInputMessage> extractor = mock();
-		OAuth2AccessTokenResponse response = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
-		given(extractor.extract(any(), any())).willReturn(Mono.just(response));
-
-		customClient.setBodyExtractor(extractor);
-
-		ClientRegistration clientRegistration = this.clientRegistrationBuilder.build();
-		OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration,
-				this.username, this.password);
-
-		this.server.enqueue(MockResponses.json("access-token-response.json"));
-
-		OAuth2AccessTokenResponse accessTokenResponse = customClient.getTokenResponse(passwordGrantRequest).block();
-		assertThat(accessTokenResponse.getAccessToken()).isNotNull();
-
-	}
-
-	private static String param(String parameterName, String parameterValue) {
-		return "%s=%s".formatted(parameterName, URLEncoder.encode(parameterValue, StandardCharsets.UTF_8));
-	}
-
-}

+ 1 - 98
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/ClientRegistrationTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -557,103 +557,6 @@ public class ClientRegistrationTests {
 			.isThrownBy(() -> TestClientRegistrations.clientCredentials().scope("an\"invalid\"scope").build());
 	}
 
-	@Test
-	public void buildWhenPasswordGrantAllAttributesProvidedThenAllAttributesAreSet() {
-		// @formatter:off
-		ClientRegistration registration = ClientRegistration.withRegistrationId(REGISTRATION_ID)
-				.clientId(CLIENT_ID)
-				.clientSecret(CLIENT_SECRET)
-				.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
-				.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-				.scope(SCOPES.toArray(new String[0]))
-				.tokenUri(TOKEN_URI)
-				.clientName(CLIENT_NAME)
-				.build();
-		// @formatter:on
-		assertThat(registration.getRegistrationId()).isEqualTo(REGISTRATION_ID);
-		assertThat(registration.getClientId()).isEqualTo(CLIENT_ID);
-		assertThat(registration.getClientSecret()).isEqualTo(CLIENT_SECRET);
-		assertThat(registration.getClientAuthenticationMethod())
-			.isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
-		assertThat(registration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.PASSWORD);
-		assertThat(registration.getScopes()).isEqualTo(SCOPES);
-		assertThat(registration.getProviderDetails().getTokenUri()).isEqualTo(TOKEN_URI);
-		assertThat(registration.getClientName()).isEqualTo(CLIENT_NAME);
-	}
-
-	@Test
-	public void buildWhenPasswordGrantRegistrationIdIsNullThenThrowIllegalArgumentException() {
-		// @formatter:off
-		assertThatIllegalArgumentException()
-				.isThrownBy(() -> ClientRegistration.withRegistrationId(null)
-						.clientId(CLIENT_ID)
-						.clientSecret(CLIENT_SECRET)
-						.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
-						.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-						.tokenUri(TOKEN_URI)
-						.build()
-				);
-		// @formatter:on
-	}
-
-	@Test
-	public void buildWhenPasswordGrantClientIdIsNullThenThrowIllegalArgumentException() {
-		// @formatter:off
-		assertThatIllegalArgumentException().isThrownBy(() -> ClientRegistration
-				.withRegistrationId(REGISTRATION_ID)
-				.clientId(null)
-				.clientSecret(CLIENT_SECRET)
-				.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
-				.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-				.tokenUri(TOKEN_URI)
-				.build()
-		);
-		// @formatter:on
-	}
-
-	@Test
-	public void buildWhenPasswordGrantClientSecretIsNullThenDefaultToEmpty() {
-		// @formatter:off
-		ClientRegistration clientRegistration = ClientRegistration.withRegistrationId(REGISTRATION_ID)
-				.clientId(CLIENT_ID)
-				.clientSecret(null)
-				.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
-				.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-				.tokenUri(TOKEN_URI)
-				.build();
-		// @formatter:on
-		assertThat(clientRegistration.getClientSecret()).isEqualTo("");
-	}
-
-	@Test
-	public void buildWhenPasswordGrantClientAuthenticationMethodNotProvidedThenDefaultToBasic() {
-		// @formatter:off
-		ClientRegistration clientRegistration = ClientRegistration.withRegistrationId(REGISTRATION_ID)
-				.clientId(CLIENT_ID)
-				.clientSecret(CLIENT_SECRET)
-				.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-				.tokenUri(TOKEN_URI)
-				.build();
-		// @formatter:on
-		assertThat(clientRegistration.getClientAuthenticationMethod())
-			.isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
-	}
-
-	@Test
-	public void buildWhenPasswordGrantTokenUriIsNullThenThrowIllegalArgumentException() {
-		// @formatter:off
-		assertThatIllegalArgumentException()
-				.isThrownBy(() -> ClientRegistration.withRegistrationId(REGISTRATION_ID)
-						.clientId(CLIENT_ID)
-						.clientSecret(CLIENT_SECRET)
-						.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
-						.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-						.tokenUri(null)
-						.build()
-				);
-		// @formatter:on
-	}
-
 	@Test
 	public void buildWhenCustomGrantAllAttributesProvidedThenAllAttributesAreSet() {
 		AuthorizationGrantType customGrantType = new AuthorizationGrantType("CUSTOM");

+ 1 - 14
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/TestClientRegistrations.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -73,17 +73,4 @@ public final class TestClientRegistrations {
 		// @formatter:on
 	}
 
-	public static ClientRegistration.Builder password() {
-		// @formatter:off
-		return ClientRegistration.withRegistrationId("password")
-				.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
-				.authorizationGrantType(AuthorizationGrantType.PASSWORD)
-				.scope("read", "write")
-				.tokenUri("https://example.com/login/oauth/access_token")
-				.clientName("Client Name")
-				.clientId("client-id")
-				.clientSecret("client-secret");
-		// @formatter:on
-	}
-
 }

+ 1 - 42
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManagerTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -16,7 +16,6 @@
 
 package org.springframework.security.oauth2.client.web;
 
-import java.util.HashMap;
 import java.util.Map;
 import java.util.function.Function;
 
@@ -46,7 +45,6 @@ import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
 import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
 import org.springframework.security.oauth2.core.TestOAuth2RefreshTokens;
 import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
-import org.springframework.util.StringUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -309,45 +307,6 @@ public class DefaultOAuth2AuthorizedClientManagerTests {
 				eq(this.request), eq(this.response));
 	}
 
-	@Test
-	public void authorizeWhenRequestParameterUsernamePasswordThenMappedToContext() {
-		given(this.clientRegistrationRepository.findByRegistrationId(eq(this.clientRegistration.getRegistrationId())))
-			.willReturn(this.clientRegistration);
-		given(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class)))
-			.willReturn(this.authorizedClient);
-		// Set custom contextAttributesMapper
-		this.authorizedClientManager.setContextAttributesMapper((authorizeRequest) -> {
-			Map<String, Object> contextAttributes = new HashMap<>();
-			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)) {
-				contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-				contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
-			}
-			return contextAttributes;
-		});
-		this.request.addParameter(OAuth2ParameterNames.USERNAME, "username");
-		this.request.addParameter(OAuth2ParameterNames.PASSWORD, "password");
-		// @formatter:off
-		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();
-		// @formatter:on
-		this.authorizedClientManager.authorize(authorizeRequest);
-		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
-		OAuth2AuthorizationContext authorizationContext = this.authorizationContextCaptor.getValue();
-		String username = authorizationContext.getAttribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME);
-		assertThat(username).isEqualTo("username");
-		String password = authorizationContext.getAttribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME);
-		assertThat(password).isEqualTo("password");
-	}
-
 	@SuppressWarnings("unchecked")
 	@Test
 	public void reauthorizeWhenUnsupportedProviderThenNotReauthorized() {

+ 1 - 40
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/DefaultReactiveOAuth2AuthorizedClientManagerTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -17,8 +17,6 @@
 package org.springframework.security.oauth2.client.web;
 
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.function.Function;
@@ -35,7 +33,6 @@ import reactor.util.context.Context;
 
 import org.springframework.core.task.SimpleAsyncTaskExecutor;
 import org.springframework.core.task.support.ExecutorServiceAdapter;
-import org.springframework.http.MediaType;
 import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
 import org.springframework.mock.web.server.MockServerWebExchange;
 import org.springframework.security.authentication.TestingAuthenticationToken;
@@ -467,42 +464,6 @@ public class DefaultReactiveOAuth2AuthorizedClientManagerTests {
 		verify(this.authorizedClientRepository, never()).removeAuthorizedClient(any(), any(), any());
 	}
 
-	@Test
-	public void authorizeWhenRequestFormParameterUsernamePasswordThenMappedToContext() {
-		given(this.clientRegistrationRepository.findByRegistrationId(eq(this.clientRegistration.getRegistrationId())))
-			.willReturn(Mono.just(this.clientRegistration));
-		given(this.authorizedClientProvider.authorize(any(OAuth2AuthorizationContext.class)))
-			.willReturn(Mono.just(this.authorizedClient));
-		// Set custom contextAttributesMapper capable of mapping the form parameters
-		this.authorizedClientManager.setContextAttributesMapper(
-				(authorizeRequest) -> currentServerWebExchange().flatMap(ServerWebExchange::getFormData)
-					.map((formData) -> {
-						Map<String, Object> contextAttributes = new HashMap<>();
-						String username = formData.getFirst(OAuth2ParameterNames.USERNAME);
-						contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-						String password = formData.getFirst(OAuth2ParameterNames.PASSWORD);
-						contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
-						return contextAttributes;
-					}));
-		this.serverWebExchange = MockServerWebExchange
-			.builder(MockServerHttpRequest.post("/")
-				.contentType(MediaType.APPLICATION_FORM_URLENCODED)
-				.body("username=username&password=password"))
-			.build();
-		this.context = Context.of(ServerWebExchange.class, this.serverWebExchange);
-		OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest
-			.withClientRegistrationId(this.clientRegistration.getRegistrationId())
-			.principal(this.principal)
-			.build();
-		this.authorizedClientManager.authorize(authorizeRequest).contextWrite(this.context).block();
-		verify(this.authorizedClientProvider).authorize(this.authorizationContextCaptor.capture());
-		OAuth2AuthorizationContext authorizationContext = this.authorizationContextCaptor.getValue();
-		String username = authorizationContext.getAttribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME);
-		assertThat(username).isEqualTo("username");
-		String password = authorizationContext.getAttribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME);
-		assertThat(password).isEqualTo("password");
-	}
-
 	@SuppressWarnings("unchecked")
 	@Test
 	public void reauthorizeWhenUnsupportedProviderThenNotReauthorized() {

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -17,8 +17,6 @@
 package org.springframework.security.oauth2.client.web.method.annotation;
 
 import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
 
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
@@ -37,29 +35,23 @@ import org.springframework.security.core.context.SecurityContextHolderStrategy;
 import org.springframework.security.core.context.SecurityContextImpl;
 import org.springframework.security.oauth2.client.ClientAuthorizationRequiredException;
 import org.springframework.security.oauth2.client.ClientCredentialsOAuth2AuthorizedClientProvider;
-import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
-import org.springframework.security.oauth2.client.PasswordOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
 import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
-import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
 import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
 import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
 import org.springframework.security.oauth2.core.AuthorizationGrantType;
 import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
 import org.springframework.security.oauth2.core.OAuth2AccessToken;
 import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.util.ReflectionUtils;
-import org.springframework.util.StringUtils;
 import org.springframework.web.context.request.ServletWebRequest;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -88,8 +80,6 @@ public class OAuth2AuthorizedClientArgumentResolverTests {
 
 	private ClientRegistration registration2;
 
-	private ClientRegistration registration3;
-
 	private ClientRegistrationRepository clientRegistrationRepository;
 
 	private OAuth2AuthorizedClient authorizedClient1;
@@ -132,12 +122,9 @@ public class OAuth2AuthorizedClientArgumentResolverTests {
 				.scope("read", "write")
 				.tokenUri("https://provider.com/oauth2/token")
 				.build();
-		this.registration3 = TestClientRegistrations.password()
-				.registrationId("client3")
-				.build();
 		// @formatter:on
 		this.clientRegistrationRepository = new InMemoryClientRegistrationRepository(this.registration1,
-				this.registration2, this.registration3);
+				this.registration2);
 		this.authorizedClientRepository = mock(OAuth2AuthorizedClientRepository.class);
 		OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
 			.authorizationCode()
@@ -307,50 +294,6 @@ public class OAuth2AuthorizedClientArgumentResolverTests {
 				any(HttpServletRequest.class), any(HttpServletResponse.class));
 	}
 
-	@SuppressWarnings("unchecked")
-	@Test
-	public void resolveArgumentWhenAuthorizedClientNotFoundForPasswordClientThenResolvesFromTokenResponseClient()
-			throws Exception {
-		OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> passwordTokenResponseClient = mock(
-				OAuth2AccessTokenResponseClient.class);
-		PasswordOAuth2AuthorizedClientProvider passwordAuthorizedClientProvider = new PasswordOAuth2AuthorizedClientProvider();
-		passwordAuthorizedClientProvider.setAccessTokenResponseClient(passwordTokenResponseClient);
-		DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
-				this.clientRegistrationRepository, this.authorizedClientRepository);
-		authorizedClientManager.setAuthorizedClientProvider(passwordAuthorizedClientProvider);
-		// Set custom contextAttributesMapper
-		authorizedClientManager.setContextAttributesMapper((authorizeRequest) -> {
-			Map<String, Object> contextAttributes = new HashMap<>();
-			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)) {
-				contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-				contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
-			}
-			return contextAttributes;
-		});
-		this.argumentResolver = new OAuth2AuthorizedClientArgumentResolver(authorizedClientManager);
-		OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse.withToken("access-token-1234")
-			.tokenType(OAuth2AccessToken.TokenType.BEARER)
-			.expiresIn(3600)
-			.build();
-		given(passwordTokenResponseClient.getTokenResponse(any())).willReturn(accessTokenResponse);
-		given(this.authorizedClientRepository.loadAuthorizedClient(anyString(), any(), any(HttpServletRequest.class)))
-			.willReturn(null);
-		MethodParameter methodParameter = this.getMethodParameter("passwordClient", OAuth2AuthorizedClient.class);
-		this.request.setParameter(OAuth2ParameterNames.USERNAME, "username");
-		this.request.setParameter(OAuth2ParameterNames.PASSWORD, "password");
-		OAuth2AuthorizedClient authorizedClient = (OAuth2AuthorizedClient) this.argumentResolver
-			.resolveArgument(methodParameter, null, new ServletWebRequest(this.request, this.response), null);
-		assertThat(authorizedClient).isNotNull();
-		assertThat(authorizedClient.getClientRegistration()).isSameAs(this.registration3);
-		assertThat(authorizedClient.getPrincipalName()).isEqualTo(this.principalName);
-		assertThat(authorizedClient.getAccessToken()).isSameAs(accessTokenResponse.getAccessToken());
-		verify(this.authorizedClientRepository).saveAuthorizedClient(eq(authorizedClient), eq(this.authentication),
-				any(HttpServletRequest.class), any(HttpServletResponse.class));
-	}
-
 	private MethodParameter getMethodParameter(String methodName, Class<?>... paramTypes) {
 		Method method = ReflectionUtils.findMethod(TestController.class, methodName, paramTypes);
 		return new MethodParameter(method, 0);
@@ -382,9 +325,6 @@ public class OAuth2AuthorizedClientArgumentResolverTests {
 				@RegisteredOAuth2AuthorizedClient("client2") OAuth2AuthorizedClient authorizedClient) {
 		}
 
-		void passwordClient(@RegisteredOAuth2AuthorizedClient("client3") OAuth2AuthorizedClient authorizedClient) {
-		}
-
 	}
 
 }

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -43,7 +43,6 @@ import org.springframework.core.codec.CharSequenceEncoder;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpMethod;
 import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
 import org.springframework.http.codec.EncoderHttpMessageWriter;
 import org.springframework.http.codec.FormHttpMessageWriter;
 import org.springframework.http.codec.HttpMessageWriter;
@@ -65,7 +64,6 @@ import org.springframework.security.oauth2.client.ClientAuthorizationException;
 import org.springframework.security.oauth2.client.ClientCredentialsReactiveOAuth2AuthorizedClientProvider;
 import org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService;
 import org.springframework.security.oauth2.client.JwtBearerReactiveOAuth2AuthorizedClientProvider;
-import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizationFailureHandler;
 import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider;
@@ -74,7 +72,6 @@ import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClient
 import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
 import org.springframework.security.oauth2.client.endpoint.JwtBearerGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
@@ -90,12 +87,10 @@ import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
 import org.springframework.security.oauth2.core.OAuth2RefreshToken;
 import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
 import org.springframework.security.oauth2.core.user.OAuth2User;
 import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.TestJwts;
-import org.springframework.util.StringUtils;
 import org.springframework.web.reactive.function.BodyInserter;
 import org.springframework.web.reactive.function.client.ClientRequest;
 import org.springframework.web.reactive.function.client.ClientResponse;
@@ -135,9 +130,6 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
 	@Mock
 	private ReactiveOAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> refreshTokenTokenResponseClient;
 
-	@Mock
-	private ReactiveOAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> passwordTokenResponseClient;
-
 	@Mock
 	private ReactiveOAuth2AccessTokenResponseClient<JwtBearerGrantRequest> jwtBearerTokenResponseClient;
 
@@ -181,7 +173,6 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
 						(configurer) -> configurer.accessTokenResponseClient(this.refreshTokenTokenResponseClient))
 				.clientCredentials(
 						(configurer) -> configurer.accessTokenResponseClient(this.clientCredentialsTokenResponseClient))
-				.password((configurer) -> configurer.accessTokenResponseClient(this.passwordTokenResponseClient))
 				.provider(jwtBearerAuthorizedClientProvider)
 				.build();
 		// @formatter:on
@@ -706,59 +697,6 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
 		verify(this.authorizationFailureHandler, never()).onAuthorizationFailure(any(), any(), any());
 	}
 
-	@Test
-	public void filterWhenPasswordClientNotAuthorizedThenGetNewToken() {
-		setupMocks();
-		TestingAuthenticationToken authentication = new TestingAuthenticationToken("test", "this");
-		ClientRegistration registration = TestClientRegistrations.password().build();
-		OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse.withToken("new-token")
-			.tokenType(OAuth2AccessToken.TokenType.BEARER)
-			.expiresIn(360)
-			.build();
-		given(this.passwordTokenResponseClient.getTokenResponse(any())).willReturn(Mono.just(accessTokenResponse));
-		given(this.clientRegistrationRepository.findByRegistrationId(eq(registration.getRegistrationId())))
-			.willReturn(Mono.just(registration));
-		given(this.authorizedClientRepository.loadAuthorizedClient(eq(registration.getRegistrationId()),
-				eq(authentication), any()))
-			.willReturn(Mono.empty());
-		// Set custom contextAttributesMapper capable of mapping the form parameters
-		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(MockServerHttpRequest.post("/")
-				.contentType(MediaType.APPLICATION_FORM_URLENCODED)
-				.body("username=username&password=password"))
-			.build();
-		ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.com"))
-			.attributes(ServerOAuth2AuthorizedClientExchangeFilterFunction
-				.clientRegistrationId(registration.getRegistrationId()))
-			.build();
-		this.function.filter(request, this.exchange)
-			.contextWrite(ReactiveSecurityContextHolder.withAuthentication(authentication))
-			.contextWrite(serverWebExchange())
-			.block();
-		verify(this.passwordTokenResponseClient).getTokenResponse(any());
-		verify(this.authorizedClientRepository).saveAuthorizedClient(any(), eq(authentication), any());
-		List<ClientRequest> requests = this.exchange.getRequests();
-		assertThat(requests).hasSize(1);
-		ClientRequest request1 = requests.get(0);
-		assertThat(request1.headers().getFirst(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer new-token");
-		assertThat(request1.url().toASCIIString()).isEqualTo("https://example.com");
-		assertThat(request1.method()).isEqualTo(HttpMethod.GET);
-		assertThat(getBody(request1)).isEmpty();
-	}
-
 	@Test
 	public void filterWhenClientRegistrationIdThenAuthorizedClientResolved() {
 		OAuth2RefreshToken refreshToken = new OAuth2RefreshToken("refresh-token", this.accessToken.getIssuedAt());

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -69,7 +69,6 @@ import org.springframework.security.core.context.SecurityContextHolderStrategy;
 import org.springframework.security.core.context.SecurityContextImpl;
 import org.springframework.security.oauth2.client.ClientAuthorizationException;
 import org.springframework.security.oauth2.client.JwtBearerOAuth2AuthorizedClientProvider;
-import org.springframework.security.oauth2.client.OAuth2AuthorizationContext;
 import org.springframework.security.oauth2.client.OAuth2AuthorizationFailureHandler;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
 import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
@@ -79,7 +78,6 @@ import org.springframework.security.oauth2.client.authentication.OAuth2Authentic
 import org.springframework.security.oauth2.client.endpoint.JwtBearerGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest;
-import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.RestClientRefreshTokenTokenResponseClient;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
@@ -95,14 +93,12 @@ import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
 import org.springframework.security.oauth2.core.OAuth2RefreshToken;
 import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
-import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
 import org.springframework.security.oauth2.core.endpoint.TestOAuth2AccessTokenResponses;
 import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;
 import org.springframework.security.oauth2.core.user.OAuth2User;
 import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.TestJwts;
 import org.springframework.test.web.client.MockRestServiceServer;
-import org.springframework.util.StringUtils;
 import org.springframework.web.client.RestClient;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
@@ -146,9 +142,6 @@ public class ServletOAuth2AuthorizedClientExchangeFilterFunctionTests {
 	@Mock
 	private OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> refreshTokenTokenResponseClient;
 
-	@Mock
-	private OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> passwordTokenResponseClient;
-
 	@Mock
 	private OAuth2AccessTokenResponseClient<JwtBearerGrantRequest> jwtBearerTokenResponseClient;
 
@@ -203,7 +196,6 @@ public class ServletOAuth2AuthorizedClientExchangeFilterFunctionTests {
 						(configurer) -> configurer.accessTokenResponseClient(this.refreshTokenTokenResponseClient))
 				.clientCredentials(
 						(configurer) -> configurer.accessTokenResponseClient(this.clientCredentialsTokenResponseClient))
-				.password((configurer) -> configurer.accessTokenResponseClient(this.passwordTokenResponseClient))
 				.provider(jwtBearerAuthorizedClientProvider)
 				.build();
 		// @formatter:on
@@ -469,51 +461,6 @@ public class ServletOAuth2AuthorizedClientExchangeFilterFunctionTests {
 		assertThat(getBody(request1)).isEmpty();
 	}
 
-	@Test
-	public void filterWhenPasswordClientNotAuthorizedThenGetNewToken() {
-		OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse.withToken("new-token")
-			.tokenType(OAuth2AccessToken.TokenType.BEARER)
-			.expiresIn(360)
-			.build();
-		given(this.passwordTokenResponseClient.getTokenResponse(any())).willReturn(accessTokenResponse);
-		ClientRegistration registration = TestClientRegistrations.password().build();
-		given(this.clientRegistrationRepository.findByRegistrationId(eq(registration.getRegistrationId())))
-			.willReturn(registration);
-		// Set custom contextAttributesMapper
-		this.authorizedClientManager.setContextAttributesMapper((authorizeRequest) -> {
-			Map<String, Object> contextAttributes = new HashMap<>();
-			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)) {
-				contextAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, username);
-				contextAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, password);
-			}
-			return contextAttributes;
-		});
-		MockHttpServletRequest servletRequest = new MockHttpServletRequest();
-		servletRequest.setParameter(OAuth2ParameterNames.USERNAME, "username");
-		servletRequest.setParameter(OAuth2ParameterNames.PASSWORD, "password");
-		MockHttpServletResponse servletResponse = new MockHttpServletResponse();
-		ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.com"))
-			.attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction
-				.clientRegistrationId(registration.getRegistrationId()))
-			.attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.authentication(this.authentication))
-			.attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.httpServletRequest(servletRequest))
-			.attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.httpServletResponse(servletResponse))
-			.build();
-		this.function.filter(request, this.exchange).block();
-		verify(this.passwordTokenResponseClient).getTokenResponse(any());
-		verify(this.authorizedClientRepository).saveAuthorizedClient(any(), eq(this.authentication), any(), any());
-		List<ClientRequest> requests = this.exchange.getRequests();
-		assertThat(requests).hasSize(1);
-		ClientRequest request1 = requests.get(0);
-		assertThat(request1.headers().getFirst(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer new-token");
-		assertThat(request1.url().toASCIIString()).isEqualTo("https://example.com");
-		assertThat(request1.method()).isEqualTo(HttpMethod.GET);
-		assertThat(getBody(request1)).isEmpty();
-	}
-
 	@Test
 	public void filterWhenJwtBearerClientNotAuthorizedThenExchangeToken() {
 		OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse.withToken("exchanged-token")

+ 3 - 12
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/AuthorizationGrantType.java

@@ -27,9 +27,9 @@ import org.springframework.util.Assert;
  * access token.
  *
  * <p>
- * The OAuth 2.0 Authorization Framework defines four standard grant types: authorization
- * code, implicit, resource owner password credentials, and client credentials. It also
- * provides an extensibility mechanism for defining additional grant types.
+ * The OAuth 2.0 Authorization Framework defines the standard grant types: authorization
+ * code, refresh token and client credentials. It also provides an extensibility mechanism
+ * for defining additional grant types.
  *
  * @author Joe Grandja
  * @author Steve Riesenberg
@@ -47,15 +47,6 @@ public final class AuthorizationGrantType implements Serializable {
 
 	public static final AuthorizationGrantType CLIENT_CREDENTIALS = new AuthorizationGrantType("client_credentials");
 
-	/**
-	 * @deprecated The OAuth 2.0 Security Best Current Practice disallows the use of the
-	 * Resource Owner Password Credentials grant. See reference <a target="_blank" href=
-	 * "https://datatracker.ietf.org/doc/html/rfc9700#section-2.4">OAuth 2.0 Security Best
-	 * Current Practice.</a>
-	 */
-	@Deprecated(since = "5.8", forRemoval = true)
-	public static final AuthorizationGrantType PASSWORD = new AuthorizationGrantType("password");
-
 	/**
 	 * @since 5.5
 	 */

+ 0 - 10
oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/OAuth2ParameterNames.java

@@ -108,16 +108,6 @@ public final class OAuth2ParameterNames {
 	 */
 	public static final String REFRESH_TOKEN = "refresh_token";
 
-	/**
-	 * {@code username} - used in Access Token Request.
-	 */
-	public static final String USERNAME = "username";
-
-	/**
-	 * {@code password} - used in Access Token Request.
-	 */
-	public static final String PASSWORD = "password";
-
 	/**
 	 * {@code error} - used in Authorization Response and Access Token Response.
 	 */

+ 1 - 6
oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/AuthorizationGrantTypeTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2025 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.
@@ -43,11 +43,6 @@ public class AuthorizationGrantTypeTests {
 		assertThat(AuthorizationGrantType.REFRESH_TOKEN.getValue()).isEqualTo("refresh_token");
 	}
 
-	@Test
-	public void getValueWhenPasswordGrantTypeThenReturnPassword() {
-		assertThat(AuthorizationGrantType.PASSWORD.getValue()).isEqualTo("password");
-	}
-
 	@Test
 	public void getValueWhenJwtBearerGrantTypeThenReturnJwtBearer() {
 		assertThat(AuthorizationGrantType.JWT_BEARER.getValue())

+ 9 - 3
test/src/main/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurers.java

@@ -827,8 +827,10 @@ public final class SecurityMockServerConfigurers {
 
 		private ClientRegistration.Builder clientRegistrationBuilder() {
 			return ClientRegistration.withRegistrationId("test")
-				.authorizationGrantType(AuthorizationGrantType.PASSWORD)
+				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
+				.redirectUri("https://client.example.com")
 				.clientId("test-client")
+				.authorizationUri("https://authorize-uri.example.org")
 				.tokenUri("https://token-uri.example.org");
 		}
 
@@ -988,8 +990,10 @@ public final class SecurityMockServerConfigurers {
 
 		private ClientRegistration.Builder clientRegistrationBuilder() {
 			return ClientRegistration.withRegistrationId("test")
-				.authorizationGrantType(AuthorizationGrantType.PASSWORD)
+				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
+				.redirectUri("https://client.example.com")
 				.clientId("test-client")
+				.authorizationUri("https://authorize-uri.example.org")
 				.tokenUri("https://token-uri.example.org");
 		}
 
@@ -1140,9 +1144,11 @@ public final class SecurityMockServerConfigurers {
 
 		private ClientRegistration.Builder clientRegistrationBuilder() {
 			return ClientRegistration.withRegistrationId(this.registrationId)
-				.authorizationGrantType(AuthorizationGrantType.PASSWORD)
+				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
+				.redirectUri("https://client.example.com")
 				.clientId("test-client")
 				.clientSecret("test-secret")
+				.authorizationUri("https://idp.example.org/oauth/authorize")
 				.tokenUri("https://idp.example.org/oauth/token");
 		}
 

+ 9 - 3
test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java

@@ -1369,8 +1369,10 @@ public final class SecurityMockMvcRequestPostProcessors {
 
 		private ClientRegistration.Builder clientRegistrationBuilder() {
 			return ClientRegistration.withRegistrationId("test")
-				.authorizationGrantType(AuthorizationGrantType.PASSWORD)
+				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
+				.redirectUri("https://client.example.com")
 				.clientId("test-client")
+				.authorizationUri("https://authorize-uri.example.org")
 				.tokenUri("https://token-uri.example.org");
 		}
 
@@ -1504,8 +1506,10 @@ public final class SecurityMockMvcRequestPostProcessors {
 
 		private ClientRegistration.Builder clientRegistrationBuilder() {
 			return ClientRegistration.withRegistrationId("test")
-				.authorizationGrantType(AuthorizationGrantType.PASSWORD)
+				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
+				.redirectUri("https://client.example.com")
 				.clientId("test-client")
+				.authorizationUri("https://authorize-uri.example.org")
 				.tokenUri("https://token-uri.example.org");
 		}
 
@@ -1627,9 +1631,11 @@ public final class SecurityMockMvcRequestPostProcessors {
 
 		private ClientRegistration.Builder clientRegistrationBuilder() {
 			return ClientRegistration.withRegistrationId(this.registrationId)
-				.authorizationGrantType(AuthorizationGrantType.PASSWORD)
+				.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
+				.redirectUri("https://client.example.com")
 				.clientId("test-client")
 				.clientSecret("test-secret")
+				.authorizationUri("https://idp.example.org/oauth/authorize")
 				.tokenUri("https://idp.example.org/oauth/token");
 		}