diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserService.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserService.java index c7b838af1f..f15a6b01c0 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserService.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserService.java @@ -19,7 +19,6 @@ package org.springframework.security.oauth2.client.oidc.userinfo; import java.time.Instant; import java.util.HashMap; import java.util.Map; -import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; @@ -27,23 +26,19 @@ import reactor.core.publisher.Mono; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.Converter; -import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.userinfo.DefaultReactiveOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.client.userinfo.ReactiveOAuth2UserService; import org.springframework.security.oauth2.core.AuthorizationGrantType; -import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.converter.ClaimConversionService; import org.springframework.security.oauth2.core.converter.ClaimTypeConverter; -import org.springframework.security.oauth2.core.oidc.OidcIdToken; import org.springframework.security.oauth2.core.oidc.OidcUserInfo; import org.springframework.security.oauth2.core.oidc.StandardClaimNames; import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; import org.springframework.security.oauth2.core.oidc.user.OidcUser; -import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.util.Assert; @@ -171,64 +166,6 @@ public class OidcReactiveOAuth2UserService implements ReactiveOAuth2UserService< this.retrieveUserInfo = retrieveUserInfo; } - /** - * Sets the {@code BiFunction} used to map the {@link OidcUser user} from the - * {@link OidcUserRequest user request} and {@link OidcUserInfo user info}. - *

- * This is useful when you need to map the user or authorities from the access token - * itself. For example, when the authorization server provides authorization - * information in the access token payload you can do the following:

-	 * 	@Bean
-	 * 	public OidcReactiveOAuth2UserService oidcUserService() {
-	 * 		var userService = new OidcReactiveOAuth2UserService();
-	 * 		userService.setOidcUserMapper(oidcUserMapper());
-	 * 		return userService;
-	 * 	}
-	 *
-	 * 	private static BiFunction<OidcUserRequest, OidcUserInfo, Mono<OidcUser>> oidcUserMapper() {
-	 * 		return (userRequest, userInfo) -> {
-	 * 			var accessToken = userRequest.getAccessToken();
-	 * 			var grantedAuthorities = new HashSet<GrantedAuthority>();
-	 * 			// TODO: Map authorities from the access token
-	 * 			var userNameAttributeName = "preferred_username";
-	 * 			return Mono.just(new DefaultOidcUser(
-	 * 				grantedAuthorities,
-	 * 				userRequest.getIdToken(),
-	 * 				userInfo,
-	 * 				userNameAttributeName
-	 * 			));
-	 * 		};
-	 * 	}
-	 * 
- *

- * Note that you can access the {@code userNameAttributeName} via the - * {@link ClientRegistration} as follows:

-	 * 	var userNameAttributeName = userRequest.getClientRegistration()
-	 * 		.getProviderDetails()
-	 * 		.getUserInfoEndpoint()
-	 * 		.getUserNameAttributeName();
-	 * 
- *

- * By default, a {@link DefaultOidcUser} is created with authorities mapped as - * follows: - *

- * @param oidcUserMapper the function used to map the {@link OidcUser} from the - * {@link OidcUserRequest} and {@link OidcUserInfo} - * @since 6.3 - * @deprecated Use {@link #setOidcUserConverter(Converter)} instead - */ - @Deprecated(since = "7.0", forRemoval = true) - public final void setOidcUserMapper(BiFunction> oidcUserMapper) { - Assert.notNull(oidcUserMapper, "oidcUserMapper cannot be null"); - this.oidcUserConverter = (source) -> oidcUserMapper.apply(source.getUserRequest(), source.getUserInfo()); - } - /** * Allows converting from the {@link OidcUserSource} to and {@link OidcUser}. * @param oidcUserConverter the {@link Converter} to use. Cannot be null. diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserService.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserService.java index 565f8917f5..9de5164da0 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserService.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserService.java @@ -19,29 +19,24 @@ package org.springframework.security.oauth2.client.oidc.userinfo; import java.time.Instant; import java.util.HashMap; import java.util.Map; -import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.Converter; -import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; import org.springframework.security.oauth2.core.AuthorizationGrantType; -import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.converter.ClaimConversionService; import org.springframework.security.oauth2.core.converter.ClaimTypeConverter; -import org.springframework.security.oauth2.core.oidc.OidcIdToken; import org.springframework.security.oauth2.core.oidc.OidcUserInfo; import org.springframework.security.oauth2.core.oidc.StandardClaimNames; import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; import org.springframework.security.oauth2.core.oidc.user.OidcUser; -import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.util.Assert; @@ -182,64 +177,6 @@ public class OidcUserService implements OAuth2UserService - * This is useful when you need to map the user or authorities from the access token - * itself. For example, when the authorization server provides authorization - * information in the access token payload you can do the following:
-	 * 	@Bean
-	 * 	public OidcUserService oidcUserService() {
-	 * 		var userService = new OidcUserService();
-	 * 		userService.setOidcUserMapper(oidcUserMapper());
-	 * 		return userService;
-	 * 	}
-	 *
-	 * 	private static BiFunction<OidcUserRequest, OidcUserInfo, OidcUser> oidcUserMapper() {
-	 * 		return (userRequest, userInfo) -> {
-	 * 			var accessToken = userRequest.getAccessToken();
-	 * 			var grantedAuthorities = new HashSet<GrantedAuthority>();
-	 * 			// TODO: Map authorities from the access token
-	 * 			var userNameAttributeName = "preferred_username";
-	 * 			return new DefaultOidcUser(
-	 * 				grantedAuthorities,
-	 * 				userRequest.getIdToken(),
-	 * 				userInfo,
-	 * 				userNameAttributeName
-	 * 			);
-	 * 		};
-	 * 	}
-	 * 
- *

- * Note that you can access the {@code userNameAttributeName} via the - * {@link ClientRegistration} as follows:

-	 * 	var userNameAttributeName = userRequest.getClientRegistration()
-	 * 		.getProviderDetails()
-	 * 		.getUserInfoEndpoint()
-	 * 		.getUserNameAttributeName();
-	 * 
- *

- * By default, a {@link DefaultOidcUser} is created with authorities mapped as - * follows: - *

- * @param oidcUserMapper the function used to map the {@link OidcUser} from the - * {@link OidcUserRequest} and {@link OidcUserInfo} - * @since 6.3 - * @deprecated Use {@link #setOidcUserConverter(Converter)} instead - */ - @Deprecated(since = "7.0", forRemoval = true) - public final void setOidcUserMapper(BiFunction oidcUserMapper) { - Assert.notNull(oidcUserMapper, "oidcUserMapper cannot be null"); - this.oidcUserConverter = (source) -> oidcUserMapper.apply(source.getUserRequest(), source.getUserInfo()); - } - /** * Allows converting from the {@link OidcUserSource} to and {@link OidcUser}. * @param oidcUserConverter the {@link Converter} to use. Cannot be null. diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserServiceTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserServiceTests.java index e3a4bb8344..95b5558b89 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserServiceTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserServiceTests.java @@ -23,7 +23,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; @@ -55,7 +54,6 @@ import org.springframework.security.oauth2.core.TestOAuth2AccessTokens; import org.springframework.security.oauth2.core.converter.ClaimTypeConverter; import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; import org.springframework.security.oauth2.core.oidc.OidcIdToken; -import org.springframework.security.oauth2.core.oidc.OidcUserInfo; import org.springframework.security.oauth2.core.oidc.StandardClaimNames; import org.springframework.security.oauth2.core.oidc.TestOidcIdTokens; import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; @@ -68,8 +66,6 @@ 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.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.same; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; @@ -225,54 +221,6 @@ public class OidcReactiveOAuth2UserServiceTests { verify(customRetrieveUserInfo).test(userRequest); } - @Test - public void loadUserWhenCustomOidcUserMapperSetThenUsed() { - Map attributes = new HashMap<>(); - attributes.put(StandardClaimNames.SUB, "subject"); - attributes.put("user", "steve"); - OAuth2User oauth2User = new DefaultOAuth2User(AuthorityUtils.createAuthorityList("ROLE_USER"), attributes, - "user"); - given(this.oauth2UserService.loadUser(any(OidcUserRequest.class))).willReturn(Mono.just(oauth2User)); - BiFunction> customOidcUserMapper = mock(BiFunction.class); - OidcUser actualUser = new DefaultOidcUser(AuthorityUtils.createAuthorityList("a", "b"), this.idToken, - IdTokenClaimNames.SUB); - given(customOidcUserMapper.apply(any(OidcUserRequest.class), any(OidcUserInfo.class))) - .willReturn(Mono.just(actualUser)); - this.userService.setOidcUserMapper(customOidcUserMapper); - OidcUserRequest userRequest = userRequest(); - OidcUser oidcUser = this.userService.loadUser(userRequest).block(); - assertThat(oidcUser).isNotNull(); - assertThat(oidcUser).isEqualTo(actualUser); - ArgumentCaptor userInfoCaptor = ArgumentCaptor.forClass(OidcUserInfo.class); - verify(customOidcUserMapper).apply(eq(userRequest), userInfoCaptor.capture()); - OidcUserInfo userInfo = userInfoCaptor.getValue(); - assertThat(userInfo.getSubject()).isEqualTo("subject"); - assertThat(userInfo.getClaimAsString("user")).isEqualTo("steve"); - } - - @Test - public void loadUserWhenCustomOidcUserMapperSetAndUserInfoNotRetrievedThenUsed() { - // @formatter:off - this.accessToken = new OAuth2AccessToken( - this.accessToken.getTokenType(), - this.accessToken.getTokenValue(), - this.accessToken.getIssuedAt(), - this.accessToken.getExpiresAt(), - Collections.emptySet()); - // @formatter:on - BiFunction> customOidcUserMapper = mock(BiFunction.class); - OidcUser actualUser = new DefaultOidcUser(AuthorityUtils.createAuthorityList("a", "b"), this.idToken, - IdTokenClaimNames.SUB); - given(customOidcUserMapper.apply(any(OidcUserRequest.class), isNull())).willReturn(Mono.just(actualUser)); - this.userService.setOidcUserMapper(customOidcUserMapper); - this.userService.setRetrieveUserInfo((oidcUserRequest) -> false); - OidcUserRequest userRequest = userRequest(); - OidcUser oidcUser = this.userService.loadUser(userRequest).block(); - assertThat(oidcUser).isNotNull(); - assertThat(oidcUser).isEqualTo(actualUser); - verify(customOidcUserMapper).apply(eq(userRequest), isNull(OidcUserInfo.class)); - } - @Test public void loadUserWhenTokenContainsScopesThenIndividualScopeAuthorities() { OidcReactiveOAuth2UserService userService = new OidcReactiveOAuth2UserService(); diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserServiceTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserServiceTests.java index 0716b4f21f..7325921404 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserServiceTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserServiceTests.java @@ -21,7 +21,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; @@ -53,7 +52,6 @@ import org.springframework.security.oauth2.core.converter.ClaimTypeConverter; import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; import org.springframework.security.oauth2.core.oidc.OidcIdToken; import org.springframework.security.oauth2.core.oidc.OidcScopes; -import org.springframework.security.oauth2.core.oidc.OidcUserInfo; import org.springframework.security.oauth2.core.oidc.StandardClaimNames; import org.springframework.security.oauth2.core.oidc.TestOidcIdTokens; import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; @@ -67,7 +65,6 @@ 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.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.same; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; @@ -138,15 +135,6 @@ public class OidcUserServiceTests { // @formatter:on } - @Test - public void setOidcUserMapperWhenNullThenThrowIllegalArgumentException() { - // @formatter:off - assertThatIllegalArgumentException() - .isThrownBy(() -> this.userService.setOidcUserMapper(null)) - .withMessage("oidcUserMapper cannot be null"); - // @formatter:on - } - @Test public void setOidcUserConverterWhenNullThenThrowIllegalArgumentException() { // @formatter:off @@ -192,37 +180,6 @@ public class OidcUserServiceTests { assertThat(user.getUserInfo()).isNotNull(); } - @Test - public void loadUserWhenCustomOidcUserMapperSetThenUsed() { - // @formatter:off - String userInfoResponse = "{\n" - + " \"sub\": \"subject1\",\n" - + " \"name\": \"first last\",\n" - + " \"given_name\": \"first\",\n" - + " \"family_name\": \"last\",\n" - + " \"preferred_username\": \"user1\",\n" - + " \"email\": \"user1@example.com\"\n" - + "}\n"; - // @formatter:on - this.server.enqueue(jsonResponse(userInfoResponse)); - String userInfoUri = this.server.url("/user").toString(); - ClientRegistration clientRegistration = this.clientRegistrationBuilder.userInfoUri(userInfoUri).build(); - this.accessToken = TestOAuth2AccessTokens.noScopes(); - BiFunction customOidcUserMapper = mock(BiFunction.class); - OidcUser actualUser = new DefaultOidcUser(AuthorityUtils.createAuthorityList("a", "b"), this.idToken, - IdTokenClaimNames.SUB); - given(customOidcUserMapper.apply(any(OidcUserRequest.class), any(OidcUserInfo.class))).willReturn(actualUser); - this.userService.setOidcUserMapper(customOidcUserMapper); - OidcUserRequest userRequest = new OidcUserRequest(clientRegistration, this.accessToken, this.idToken); - OidcUser user = this.userService.loadUser(userRequest); - assertThat(user).isEqualTo(actualUser); - ArgumentCaptor userInfoCaptor = ArgumentCaptor.forClass(OidcUserInfo.class); - verify(customOidcUserMapper).apply(eq(userRequest), userInfoCaptor.capture()); - OidcUserInfo userInfo = userInfoCaptor.getValue(); - assertThat(userInfo.getSubject()).isEqualTo("subject1"); - assertThat(userInfo.getClaimAsString("preferred_username")).isEqualTo("user1"); - } - @Test public void loadUserWhenCustomOidcUserConverterSetThenUsed() { ClientRegistration clientRegistration = this.clientRegistrationBuilder.userInfoUri("https://example.com/user")