Skip to content

Commit

Permalink
Request user info when AS returns no scopes
Browse files Browse the repository at this point in the history
  • Loading branch information
sjohnr committed Nov 8, 2022
1 parent 8cde8fb commit c10b87b
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,15 @@ private boolean shouldRetrieveUserInfo(OidcUserRequest userRequest) {
.equals(userRequest.getClientRegistration().getAuthorizationGrantType())) {
// Return true if there is at least one match between the authorized scope(s)
// and accessible scope(s)
// As per spec, in Section 5.1 Successful Access Token Response
// https://www.rfc-editor.org/rfc/rfc6749#section-5.1
// If AccessTokenResponse.scope is empty, then default to the scope
// originally requested by the client in the Token Request
// @formatter:off
return this.accessibleScopes.isEmpty()
|| CollectionUtils.isEmpty(userRequest.getAccessToken().getScopes())
|| CollectionUtils.containsAny(userRequest.getAccessToken().getScopes(), this.accessibleScopes);
// @formatter:on
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,14 +458,36 @@ public void loadUserWhenTokenContainsScopesThenIndividualScopeAuthorities() {
@Test
public void loadUserWhenTokenDoesNotContainScopesThenNoScopeAuthorities() {
OidcUserService userService = new OidcUserService();
OidcUserRequest request = new OidcUserRequest(TestClientRegistrations.clientRegistration().build(),
TestOAuth2AccessTokens.noScopes(), TestOidcIdTokens.idToken().build());
OidcUserRequest request = new OidcUserRequest(this.clientRegistrationBuilder.build(),
TestOAuth2AccessTokens.noScopes(), this.idToken);
OidcUser user = userService.loadUser(request);
assertThat(user.getAuthorities()).hasSize(1);
Iterator<? extends GrantedAuthority> authorities = user.getAuthorities().iterator();
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\": \"[email protected]\"\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) {
// @formatter:off
return new MockResponse()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@

package org.springframework.security.oauth2.core.endpoint;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;

/**
Expand All @@ -42,7 +44,8 @@ public static OAuth2AccessTokenResponse.Builder accessTokenResponse() {
public static OAuth2AccessTokenResponse.Builder oidcAccessTokenResponse() {
Map<String, Object> additionalParameters = new HashMap<>();
additionalParameters.put(OidcParameterNames.ID_TOKEN, "id-token");
return accessTokenResponse().additionalParameters(additionalParameters);
return accessTokenResponse().scopes(Collections.singleton(OidcScopes.OPENID))
.additionalParameters(additionalParameters);
}

}

0 comments on commit c10b87b

Please sign in to comment.