springspring-security

OidcUserService.setAccessibleScopes deprecated


OidcUserService.setAccessibleScopes is depreacted. We are creating the OidcUserService like this:

final OidcUserService oidcUserService = new OidcUserService();
    oidcUserService.setOauth2UserService(userService);
    oidcUserService.setAccessibleScopes(
        Set.of(
            OidcScopes.PROFILE,
            OidcScopes.EMAIL,
            OidcScopes.ADDRESS,
            OidcScopes.PHONE,
            OidcScopes.OPENID));
    return oidcUserService;

The deprecated hint is to use .setRetrieveUserInfo(). But how?

I've tried this:

oidcUserService.setRetrieveUserInfo(oidcUserRequest -> oidcUserRequest.getClientRegistration().getScopes().addAll(Set.of(
            OidcScopes.PROFILE,
            OidcScopes.EMAIL,
            OidcScopes.ADDRESS,
            OidcScopes.PHONE,
            OidcScopes.OPENID)));

but scopes is a UnmodefiableCollection.

Thanks for your replies.


Solution

  • The default implementation checks the accessibleScopes which is something you should now do yourselves as that is more flexible. The setRetrieveUserInfo accepts a Predicate which is just for testing something (a request comes in a boolean comes out).

    What you should write is something like this.

    
    private boolean customShouldRetrieveUserInfo(OidcUserRequest userRequest) {
      var final scopes = Set.of(OidcScopes.PROFILE,
                OidcScopes.EMAIL,
                OidcScopes.ADDRESS,
                OidcScopes.PHONE,
                OidcScopes.OPENID);
        ProviderDetails providerDetails = userRequest.getClientRegistration().getProviderDetails();
        if (!StringUtils.hasLength(providerDetails.getUserInfoEndpoint().getUri())) {
            return false;
        }
    
        if (AuthorizationGrantType.AUTHORIZATION_CODE
            .equals(userRequest.getClientRegistration().getAuthorizationGrantType())) {
            return this.accessibleScopes.isEmpty()
                    || CollectionUtils.isEmpty(userRequest.getAccessToken().getScopes())
                    || CollectionUtils.containsAny(userRequest.getAccessToken().getScopes(), scopes);
        }
        return false;
    }
    

    This is a method you can use as the predicate (inspired by the original method).

    final OidcUserService oidcUserService = new OidcUserService();
        oidcUserService.setOauth2UserService(userService);
        oidcUserService.setRetrieveUserInfo(this::customShouldRetrieveUserInfo);
        return oidcUserService;
    

    Something like this.