0

I have multiple clients registered for my oauth2 auth server. I want to get the user authorities based on the clientId. Let's say USER-1 has authorities ADMIN for CLIENT-1 and for CLIENT-2 the USER-1 has USER authority.

I have tried this issue. But I always get a null request.

final HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();

I have also added a WebListner, but with no luck.

@Configuration
@WebListener
public class MyRequestContextListener extends RequestContextListener {

}
@Service
public class DomainUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private AuthorityRepository authorityRepository;

    @Override
    @Transactional
    public UserDetails loadUserByUsername(final String email) throws UsernameNotFoundException {
        User user = userRepository.findUserByUserName(email);
        if (user == null) {
            new UsernameNotFoundException("Username not found");
        }

        String clientId = "?"; // How to get clientId here?
        List<String> roles = authorityRepository.getUserAuthorities(email, clientId);

        return new DomainUser(email, user.getCredential(), user.getId(), fillUserAuthorities(roles));
    }

    public Collection<SimpleGrantedAuthority> fillUserAuthorities(Collection<String> roles) {
        Collection<SimpleGrantedAuthority> authorties = new ArrayList<SimpleGrantedAuthority>();
        for (String role : roles) {
            authorties.add(new SimpleGrantedAuthority(role.toUpperCase()));
        }
        return authorties;
    }
}

If I am going in the wrong direction, any suggestions are acceptable.

entpnerd
  • 10,049
  • 8
  • 47
  • 68
  • Where do you have clientId available? – Shariq Jan 23 '19 at 05:47
  • Hi sir, I am using spring-security-oauth2. I want to get the access_token using Grant Type "Authorization code". So at first user need to give his identity to the AuthorizationServer. During the process, I want to access the clientId. – Subhakant Priyadarsan Jan 23 '19 at 07:02
  • You can append clientId along with email ID using separator like ';' while calling authenticate(). Hence in loadByUserName, you can split the string by ; and get email as well as clientId. – Shariq Jan 23 '19 at 09:11
  • The username will be entered by end users. Why end users should know what is the clientId? – Subhakant Priyadarsan Jan 23 '19 at 09:31

1 Answers1

1

Currently, I am using a Custom JWT Token Enhancer to achieve the requirement. But I am not sure if this is the right way of doing this. I am not sure why I'm thinking it is the wrong way. But you can achieve this using the below solution.

public class CustomTokenEnhancer implements TokenEnhancer {

    @Autowired
    private AuthorityRepository authRepository;

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        Map<String, Object> additionalInfo = new HashMap<>();
        DomainUser authPrincipal = (DomainUser) authentication.getPrincipal();
        List<String> clientBasedRoles = authRepository.getUserAuthorities(authPrincipal.getId(),
                authentication.getOAuth2Request().getClientId());
        additionalInfo.put("authorities", clientBasedRoles);
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
        return accessToken;
    }
}

Then, in your AuthorizationServerConfigurerAdapter.

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));
        endpoints.authenticationManager(this.authenticationManager).accessTokenConverter(accessTokenConverter())
                .tokenEnhancer(tokenEnhancerChain);
    }
}