0

Good Day,

My situations is as follows. I have one resource server and two authorization servers.

The first authorization server(Not maintained by us) uses a set of jwks to sign jwt token whenever someone logs in via their portal. Our resource server is already configured to verify the signature of the tokens using "JwkTokenStore(url path to jwks)".

I now want to configure our authorization server to sign jwt tokens using the same jwks set when someone logs in via our portal.

The idea being that if the tokens are signed in the same way, the resource server should be able to verify the signature regardless of which auth server issued the tokens.

Is this a feesable solution to the question of having two auth servers and one resource server ?

Below is snippets of how the resource server is configured.

Resource Server Config

@Configuration
@EnableResourceServer
@Order(3)
@Slf4j
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
    private String keys;
    @Autowired
    private CustomAccessTokenConverter customAccessTokenConverter;

    @Override
    public void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests().authenticated().and().oauth2ResourceServer().jwt();
    }

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

    @Bean TokenStore tokenStore() throws IOException {
        JwkTokenStore store = new JwkTokenStore(keys);
        return store;
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setAccessTokenConverter(customAccessTokenConverter);
        return converter;
    }


    @Bean
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        try {
            defaultTokenServices.setTokenStore(tokenStore());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return defaultTokenServices;
    }
}  

CustomAccessTokenConverter

@Component
public class CustomAccessTokenConverter extends DefaultAccessTokenConverter {

    @Override
    public OAuth2Authentication extractAuthentication(Map<String, ?> claims) {
        OAuth2Authentication authentication = super.extractAuthentication(claims);
        authentication.setDetails(claims);
        return authentication;
    }
}  

Application Properties

spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://auth.server.one/keys.json

So how do I go about configuring our own auth server so that it signs jwt tokens using the same jwks set of keys. I have the following so far but the error I get is when trying to login with password grant.

"Handling error: JwkException, This operation is not supported."

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws  Exception {
        clients.inMemory()
            .withClient(clientId)
            .secret(passwordEncoder.encode(clientSecret))
            .scopes("read")
            .accessTokenValiditySeconds(300)
            .refreshTokenValiditySeconds(86400)
            .authorizedGrantTypes("client_credentials", "password", "refresh_token");
    }

    @Bean
    public TokenStore tokenStore() {
        JwkTokenStore store = new JwkTokenStore("https://auth.server.one/keys.json");
        return store;
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        return converter;
    }
}

Any help will be greatly appreciated. Thanks All

Lyle Phillips
  • 197
  • 4
  • 13
  • To sign a token you would need a private key and I assume the external authorization server does not expose the private key in a JWKS (otherwise it wouldn't be private anymore!). Usually, only the public keys are exposed through a JWKS to allow verification of tokens. – jps Oct 26 '22 at 09:16
  • Thanks for taking the time. Understood so my solution will not work. So I guess now I will have to make the resource server multi tenant right ? – Lyle Phillips Oct 26 '22 at 09:52
  • Yes, that would be the way to go. Usually, the issuer claim in the token ("iss") should tell the resource server where to look for the right public key for verification. – jps Oct 26 '22 at 09:58
  • So then how would I set it up bc i'd have to have two "spring.security.oauth2.resourceserver.jwt.jwk-set-uri" properties right ? – Lyle Phillips Oct 26 '22 at 10:12
  • Sorry, I'm not an expert in spring/spring-security. At his point, I think it would make more sense to either search for a suitable answer here on Stackoverflow or ask a new question. – jps Oct 26 '22 at 10:41
  • Okay cool Thanks for your help am doing that right now – Lyle Phillips Oct 26 '22 at 10:44

0 Answers0