Skip to content

Commit af1de95

Browse files
committed
Align setRetrieveUserInfo() between OidcUserService and OidcReactiveOAuth2UserService
Closes gh-18057
1 parent 7f29585 commit af1de95

5 files changed

Lines changed: 17 additions & 65 deletions

File tree

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserService.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,14 @@ public final void setClaimTypeConverterFactory(
156156
* Sets the {@code Predicate} used to determine if the UserInfo Endpoint should be
157157
* called to retrieve information about the End-User (Resource Owner).
158158
* <p>
159-
* By default, the UserInfo Endpoint is called if all of the following are true:
159+
* By default, the UserInfo Endpoint is called if all the following are true:
160160
* <ul>
161161
* <li>The user info endpoint is defined on the ClientRegistration</li>
162162
* <li>The Client Registration uses the
163-
* {@link AuthorizationGrantType#AUTHORIZATION_CODE} and scopes in the access token
164-
* are defined in the {@link ClientRegistration}</li>
163+
* {@link AuthorizationGrantType#AUTHORIZATION_CODE}</li>
165164
* </ul>
166-
* @param retrieveUserInfo the function used to determine if the UserInfo Endpoint
167-
* should be called
165+
* @param retrieveUserInfo the {@code Predicate} used to determine if the UserInfo
166+
* Endpoint should be called
168167
* @since 6.3
169168
*/
170169
public final void setRetrieveUserInfo(Predicate<OidcUserRequest> retrieveUserInfo) {

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserRequestUtils.java

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
2929
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
3030
import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
31-
import org.springframework.util.CollectionUtils;
3231
import org.springframework.util.StringUtils;
3332

3433
/**
@@ -40,38 +39,24 @@
4039
final class OidcUserRequestUtils {
4140

4241
/**
43-
* Determines if an {@link OidcUserRequest} should attempt to retrieve the user info
44-
* endpoint. Will return true if all of the following are true:
42+
* Determines if an {@link OidcUserRequest} should attempt to retrieve the user info.
43+
* Will return true if all the following are true:
4544
*
4645
* <ul>
4746
* <li>The user info endpoint is defined on the ClientRegistration</li>
4847
* <li>The Client Registration uses the
49-
* {@link AuthorizationGrantType#AUTHORIZATION_CODE} and scopes in the access token
50-
* are defined in the {@link ClientRegistration}</li>
48+
* {@link AuthorizationGrantType#AUTHORIZATION_CODE}</li>
5149
* </ul>
5250
* @param userRequest
5351
* @return
5452
*/
5553
static boolean shouldRetrieveUserInfo(OidcUserRequest userRequest) {
5654
// Auto-disabled if UserInfo Endpoint URI is not provided
57-
ClientRegistration clientRegistration = userRequest.getClientRegistration();
58-
if (!StringUtils.hasLength(clientRegistration.getProviderDetails().getUserInfoEndpoint().getUri())) {
59-
return false;
60-
}
61-
// The Claims requested by the profile, email, address, and phone scope values
62-
// are returned from the UserInfo Endpoint (as described in Section 5.3.2),
63-
// when a response_type value is used that results in an Access Token being
64-
// issued.
65-
// However, when no Access Token is issued, which is the case for the
66-
// response_type=id_token,
67-
// the resulting Claims are returned in the ID Token.
68-
// The Authorization Code Grant Flow, which is response_type=code, results in an
69-
// Access Token being issued.
70-
if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(clientRegistration.getAuthorizationGrantType())) {
71-
// Return true if there is at least one match between the authorized scope(s)
72-
// and UserInfo scope(s)
73-
return CollectionUtils.containsAny(userRequest.getAccessToken().getScopes(),
74-
userRequest.getClientRegistration().getScopes());
55+
ClientRegistration.ProviderDetails providerDetails = userRequest.getClientRegistration().getProviderDetails();
56+
if (StringUtils.hasLength(providerDetails.getUserInfoEndpoint().getUri())
57+
&& AuthorizationGrantType.AUTHORIZATION_CODE
58+
.equals(userRequest.getClientRegistration().getAuthorizationGrantType())) {
59+
return true;
7560
}
7661
return false;
7762
}

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserService.java

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.springframework.core.convert.converter.Converter;
2828
import org.springframework.security.core.authority.SimpleGrantedAuthority;
2929
import org.springframework.security.oauth2.client.registration.ClientRegistration;
30-
import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails;
3130
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
3231
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
3332
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
@@ -45,7 +44,6 @@
4544
import org.springframework.security.oauth2.core.oidc.user.OidcUserAuthority;
4645
import org.springframework.security.oauth2.core.user.OAuth2User;
4746
import org.springframework.util.Assert;
48-
import org.springframework.util.StringUtils;
4947

5048
/**
5149
* An implementation of an {@link OAuth2UserService} that supports OpenID Connect 1.0
@@ -72,7 +70,7 @@ public class OidcUserService implements OAuth2UserService<OidcUserRequest, OidcU
7270
private Function<ClientRegistration, Converter<Map<String, Object>, Map<String, Object>>> claimTypeConverterFactory = (
7371
clientRegistration) -> DEFAULT_CLAIM_TYPE_CONVERTER;
7472

75-
private Predicate<OidcUserRequest> retrieveUserInfo = this::shouldRetrieveUserInfo;
73+
private Predicate<OidcUserRequest> retrieveUserInfo = OidcUserRequestUtils::shouldRetrieveUserInfo;
7674

7775
private Converter<OidcUserSource, OidcUser> oidcUserConverter = OidcUserRequestUtils::getUser;
7876

@@ -139,17 +137,6 @@ private Map<String, Object> getClaims(OidcUserRequest userRequest, OAuth2User oa
139137
return DEFAULT_CLAIM_TYPE_CONVERTER.convert(oauth2User.getAttributes());
140138
}
141139

142-
private boolean shouldRetrieveUserInfo(OidcUserRequest userRequest) {
143-
// Auto-disabled if UserInfo Endpoint URI is not provided
144-
ProviderDetails providerDetails = userRequest.getClientRegistration().getProviderDetails();
145-
if (StringUtils.hasLength(providerDetails.getUserInfoEndpoint().getUri())
146-
&& AuthorizationGrantType.AUTHORIZATION_CODE
147-
.equals(userRequest.getClientRegistration().getAuthorizationGrantType())) {
148-
return true;
149-
}
150-
return false;
151-
}
152-
153140
/**
154141
* Sets the {@link OAuth2UserService} used when requesting the user info resource.
155142
* @param oauth2UserService the {@link OAuth2UserService} used when requesting the

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcReactiveOAuth2UserServiceTests.java

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -199,22 +199,6 @@ public void loadUserWhenCustomClaimTypeConverterFactorySetThenApplied() {
199199
verify(customClaimTypeConverterFactory).apply(same(userRequest.getClientRegistration()));
200200
}
201201

202-
@Test
203-
public void loadUserWhenTokenScopesIsEmptyThenUserInfoNotRetrieved() {
204-
// @formatter:off
205-
OAuth2AccessToken accessToken = new OAuth2AccessToken(
206-
this.accessToken.getTokenType(),
207-
this.accessToken.getTokenValue(),
208-
this.accessToken.getIssuedAt(),
209-
this.accessToken.getExpiresAt(),
210-
Collections.emptySet());
211-
// @formatter:on
212-
OidcUserRequest userRequest = new OidcUserRequest(this.registration.build(), accessToken, this.idToken);
213-
OidcUser oidcUser = this.userService.loadUser(userRequest).block();
214-
assertThat(oidcUser).isNotNull();
215-
assertThat(oidcUser.getUserInfo()).isNull();
216-
}
217-
218202
@Test
219203
public void loadUserWhenCustomRetrieveUserInfoSetThenUsed() {
220204
Map<String, Object> attributes = new HashMap<>();
@@ -281,6 +265,7 @@ public void loadUserWhenCustomOidcUserMapperSetAndUserInfoNotRetrievedThenUsed()
281265
IdTokenClaimNames.SUB);
282266
given(customOidcUserMapper.apply(any(OidcUserRequest.class), isNull())).willReturn(Mono.just(actualUser));
283267
this.userService.setOidcUserMapper(customOidcUserMapper);
268+
this.userService.setRetrieveUserInfo((oidcUserRequest) -> false);
284269
OidcUserRequest userRequest = userRequest();
285270
OidcUser oidcUser = this.userService.loadUser(userRequest).block();
286271
assertThat(oidcUser).isNotNull();
@@ -291,6 +276,7 @@ public void loadUserWhenCustomOidcUserMapperSetAndUserInfoNotRetrievedThenUsed()
291276
@Test
292277
public void loadUserWhenTokenContainsScopesThenIndividualScopeAuthorities() {
293278
OidcReactiveOAuth2UserService userService = new OidcReactiveOAuth2UserService();
279+
userService.setRetrieveUserInfo((oidcUserRequest) -> false);
294280
OidcUserRequest request = new OidcUserRequest(TestClientRegistrations.clientRegistration().build(),
295281
TestOAuth2AccessTokens.scopes("message:read", "message:write"), TestOidcIdTokens.idToken().build());
296282
OidcUser user = userService.loadUser(request).block();
@@ -304,6 +290,7 @@ public void loadUserWhenTokenContainsScopesThenIndividualScopeAuthorities() {
304290
@Test
305291
public void loadUserWhenTokenDoesNotContainScopesThenNoScopeAuthorities() {
306292
OidcReactiveOAuth2UserService userService = new OidcReactiveOAuth2UserService();
293+
userService.setRetrieveUserInfo((oidcUserRequest) -> false);
307294
OidcUserRequest request = new OidcUserRequest(TestClientRegistrations.clientRegistration().build(),
308295
TestOAuth2AccessTokens.noScopes(), TestOidcIdTokens.idToken().build());
309296
OidcUser user = userService.loadUser(request).block();

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/userinfo/OidcUserRequestUtilsTests.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public class OidcUserRequestUtilsTests {
4545
Instant.now().plus(Duration.ofDays(1)), Collections.singleton("read:user"));
4646

4747
@Test
48-
public void shouldRetrieveUserInfoWhenEndpointDefinedAndScopesOverlapThenTrue() {
48+
public void shouldRetrieveUserInfoWhenUserInfoUriThenTrue() {
4949
assertThat(OidcUserRequestUtils.shouldRetrieveUserInfo(userRequest())).isTrue();
5050
}
5151

@@ -55,12 +55,6 @@ public void shouldRetrieveUserInfoWhenNoUserInfoUriThenFalse() {
5555
assertThat(OidcUserRequestUtils.shouldRetrieveUserInfo(userRequest())).isFalse();
5656
}
5757

58-
@Test
59-
public void shouldRetrieveUserInfoWhenDifferentScopesThenFalse() {
60-
this.registration.scope("notintoken");
61-
assertThat(OidcUserRequestUtils.shouldRetrieveUserInfo(userRequest())).isFalse();
62-
}
63-
6458
@Test
6559
public void shouldRetrieveUserInfoWhenNotAuthorizationCodeThenFalse() {
6660
this.registration.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS);

0 commit comments

Comments
 (0)