Request user info when AS returns no scopes
Closes gh-12144
This commit is contained in:
parent
8cde8fb363
commit
fde26e003a
|
@ -173,8 +173,14 @@ public class OidcUserService implements OAuth2UserService<OidcUserRequest, OidcU
|
||||||
.equals(userRequest.getClientRegistration().getAuthorizationGrantType())) {
|
.equals(userRequest.getClientRegistration().getAuthorizationGrantType())) {
|
||||||
// Return true if there is at least one match between the authorized scope(s)
|
// Return true if there is at least one match between the authorized scope(s)
|
||||||
// and accessible scope(s)
|
// and accessible scope(s)
|
||||||
|
//
|
||||||
|
// Also return true if authorized scope(s) is empty, because the provider has
|
||||||
|
// not indicated which scopes are accessible via the access token
|
||||||
|
// @formatter:off
|
||||||
return this.accessibleScopes.isEmpty()
|
return this.accessibleScopes.isEmpty()
|
||||||
|
|| CollectionUtils.isEmpty(userRequest.getAccessToken().getScopes())
|
||||||
|| CollectionUtils.containsAny(userRequest.getAccessToken().getScopes(), this.accessibleScopes);
|
|| CollectionUtils.containsAny(userRequest.getAccessToken().getScopes(), this.accessibleScopes);
|
||||||
|
// @formatter:on
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -458,14 +458,36 @@ public class OidcUserServiceTests {
|
||||||
@Test
|
@Test
|
||||||
public void loadUserWhenTokenDoesNotContainScopesThenNoScopeAuthorities() {
|
public void loadUserWhenTokenDoesNotContainScopesThenNoScopeAuthorities() {
|
||||||
OidcUserService userService = new OidcUserService();
|
OidcUserService userService = new OidcUserService();
|
||||||
OidcUserRequest request = new OidcUserRequest(TestClientRegistrations.clientRegistration().build(),
|
OidcUserRequest request = new OidcUserRequest(this.clientRegistrationBuilder.build(),
|
||||||
TestOAuth2AccessTokens.noScopes(), TestOidcIdTokens.idToken().build());
|
TestOAuth2AccessTokens.noScopes(), this.idToken);
|
||||||
OidcUser user = userService.loadUser(request);
|
OidcUser user = userService.loadUser(request);
|
||||||
assertThat(user.getAuthorities()).hasSize(1);
|
assertThat(user.getAuthorities()).hasSize(1);
|
||||||
Iterator<? extends GrantedAuthority> authorities = user.getAuthorities().iterator();
|
Iterator<? extends GrantedAuthority> authorities = user.getAuthorities().iterator();
|
||||||
assertThat(authorities.next()).isInstanceOf(OidcUserAuthority.class);
|
assertThat(authorities.next()).isInstanceOf(OidcUserAuthority.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadUserWhenTokenDoesNotContainScopesAndUserInfoUriThenUserInfoRequested() {
|
||||||
|
// @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();
|
||||||
|
OidcUserService userService = new OidcUserService();
|
||||||
|
OidcUserRequest request = new OidcUserRequest(clientRegistration, TestOAuth2AccessTokens.noScopes(),
|
||||||
|
this.idToken);
|
||||||
|
OidcUser user = userService.loadUser(request);
|
||||||
|
assertThat(user.getUserInfo()).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
private MockResponse jsonResponse(String json) {
|
private MockResponse jsonResponse(String json) {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
return new MockResponse()
|
return new MockResponse()
|
||||||
|
|
|
@ -16,10 +16,12 @@
|
||||||
|
|
||||||
package org.springframework.security.oauth2.core.endpoint;
|
package org.springframework.security.oauth2.core.endpoint;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||||
|
import org.springframework.security.oauth2.core.oidc.OidcScopes;
|
||||||
import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;
|
import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,7 +44,8 @@ public final class TestOAuth2AccessTokenResponses {
|
||||||
public static OAuth2AccessTokenResponse.Builder oidcAccessTokenResponse() {
|
public static OAuth2AccessTokenResponse.Builder oidcAccessTokenResponse() {
|
||||||
Map<String, Object> additionalParameters = new HashMap<>();
|
Map<String, Object> additionalParameters = new HashMap<>();
|
||||||
additionalParameters.put(OidcParameterNames.ID_TOKEN, "id-token");
|
additionalParameters.put(OidcParameterNames.ID_TOKEN, "id-token");
|
||||||
return accessTokenResponse().additionalParameters(additionalParameters);
|
return accessTokenResponse().scopes(Collections.singleton(OidcScopes.OPENID))
|
||||||
|
.additionalParameters(additionalParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue