2

I'm using Spring Boot OAuth Authorization Server (old stack) and implementing my own versions of ClientDetailsService and UserDetailsService, using Oauth2 password flow.

Our JpaClientDetailsService implements loadClientByClientId and returns a ClientDetails, with the details of the client that is being authenticated.

@Service
public class JpaClientDetailsService implements ClientDetailsService {

    @Override
    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
    
        BaseClientDetails baseClientDetails = new BaseClientDetails(...);

        //do processing....

        return baseClientDetails;

    }

}

After that, the method loadUserByUsername of our implementation of JpaUserDetailsService is called, receiving the username of user that is trying to authenticate:

@Service
public class JpaUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        return null;

    }

}

My question is: How could I access the current ClientDetails, returned by JpaClientDetailsService.loadClientByClientId inside JpaUserDetailsService.loadUserByUsername?

Thanks!

regisxp
  • 956
  • 2
  • 10
  • 31

1 Answers1

1

I realized that SecurityContextHolder.getContext().getAuthentication() contains information about the client that is being authenticated. So, I was able to get the client's name and load it's data as follow:

@Service
public class JpaUserDetailsService implements UserDetailsService {

    @Autowired
    private OAuthClientsRepository oAuthClientsRepository;

    @Override
    public org.springframework.security.core.userdetails.UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //Gets the Authentication from SecurityContextHolder
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        
        //ClientId is 'Principal's' Username
        var clientId = ((User) authentication.getPrincipal()).getUsername();

        //Gets clientDetails from JPA Repository. This would execute another Roundtrip to Database, but since we have 2nd level cache configured, this
        //problema is minimized.
        ClientDetails authClient = oAuthClientsRepository
                .findByClientId(clientId)
                .orElseThrow(() -> new NoSuchClientException(String.format("ClientId '%s' not found", clientId)));

        //....

    }

}

That's it.

regisxp
  • 956
  • 2
  • 10
  • 31