Skip to content

Improve customization of DefaultOAuth2UserService to handle other content types #9629

Open
@knoobie

Description

@knoobie

Expected Behavior

DefaultOAuth2UserService can be extended to e.g. allow for custom body parsing to handle application/jwtfor signed and/or encrypted UserInfo Response.

Rough draft:

public class CustomOAuth2UserService extends DefaultOAuth2UserService {

   @Override
    protected ResponseEntity<Map<String, Object>> getResponse(OAuth2UserRequest userRequest, RequestEntity<?> request) {
      // Custom code to handle requests that aren't simple application/json
      return ...;
     }
}

We are open for other solutions as well and happy to contribute, if that's something you see worth it as addition to spring-security.

Current Behavior

DefaultOAuth2UserService has to be copied and "rewritten" - because getResponse() is called inside loadUser(OAuth2UserRequest userRequest) which forces us to re-create the whole loadUser(OAuth2UserRequest userRequest) method.

public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
Assert.notNull(userRequest, "userRequest cannot be null");
if (!StringUtils
.hasText(userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri())) {
OAuth2Error oauth2Error = new OAuth2Error(MISSING_USER_INFO_URI_ERROR_CODE,
"Missing required UserInfo Uri in UserInfoEndpoint for Client Registration: "
+ userRequest.getClientRegistration().getRegistrationId(),
null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint()
.getUserNameAttributeName();
if (!StringUtils.hasText(userNameAttributeName)) {
OAuth2Error oauth2Error = new OAuth2Error(MISSING_USER_NAME_ATTRIBUTE_ERROR_CODE,
"Missing required \"user name\" attribute name in UserInfoEndpoint for Client Registration: "
+ userRequest.getClientRegistration().getRegistrationId(),
null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
RequestEntity<?> request = this.requestEntityConverter.convert(userRequest);
ResponseEntity<Map<String, Object>> response = getResponse(userRequest, request);
Map<String, Object> userAttributes = response.getBody();
Set<GrantedAuthority> authorities = new LinkedHashSet<>();
authorities.add(new OAuth2UserAuthority(userAttributes));
OAuth2AccessToken token = userRequest.getAccessToken();
for (String authority : token.getScopes()) {
authorities.add(new SimpleGrantedAuthority("SCOPE_" + authority));
}
return new DefaultOAuth2User(authorities, userAttributes, userNameAttributeName);
}

Context

Related to #9583

Metadata

Metadata

Assignees

Labels

in: oauth2An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions