6

I am unable to extract user info from the access token generated by keycloak. I have a protected route where I am expecting Principal or Authentication objects to be populated correctly.

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    private final String SIGNING_KEY = "MIIBCgKCAQ...AB";

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .requestMatcher(new RequestHeaderRequestMatcher("Authorization"))
                .authorizeRequests()
                .antMatchers("/api/register").anonymous()
                .antMatchers("/api/token").anonymous()
                .anyRequest().authenticated();
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer config) {
        config.tokenServices(createTokenServices());
    }

    @Bean
    @Primary
    public DefaultTokenServices createTokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(createTokenStore());
        return defaultTokenServices;
    }

    @Bean
    public TokenStore createTokenStore() {
        return new JwtTokenStore(createJwtAccessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter createJwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setAccessTokenConverter(new JwtConverter());
//        converter.setSigningKey(SIGNING_KEY);
        return converter;
    }

    public static class JwtConverter extends DefaultAccessTokenConverter implements JwtAccessTokenConverterConfigurer {

        @Override
        public void configure(JwtAccessTokenConverter converter) {
            converter.setAccessTokenConverter(this);
        }

        @Override
        public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
            OAuth2Authentication auth = super.extractAuthentication(map);
            auth.setDetails(map); //this will get spring to copy JWT content into Authentication
            return auth;
        }
    }
}

In Profile controller, I would like to display the details from the token passed in.

    @GetMapping("/api/profile/details")
    public Object details(final Principal authentication) {

//        Object details = authentication.getDetails();
//        if (details instanceof OAuth2AuthenticationDetails) {
//            OAuth2AuthenticationDetails oAuth2AuthenticationDetails = (OAuth2AuthenticationDetails) details;
//            Map<String, Object> decodedDetails = (Map<String, Object>) oAuth2AuthenticationDetails.getDecodedDetails();
//
//            return decodedDetails;
//        }

        return authentication.getName();
    }

I get the following error when I call the above endpooint.

{
    "error": "invalid_token",
    "error_description": "Cannot convert access token to JSON"
}

Whether I pass in the signing key or not it doesn't make a difference.

Thanks for helping.

Chirdeep Tomar
  • 4,281
  • 8
  • 37
  • 66

0 Answers0