Skip to content

How to increase RemoteJwkSet timeout? #10610

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
andreas-trvlk opened this issue Dec 15, 2021 · 8 comments
Closed

How to increase RemoteJwkSet timeout? #10610

andreas-trvlk opened this issue Dec 15, 2021 · 8 comments
Assignees
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) status: invalid An issue that we don't feel is valid

Comments

@andreas-trvlk
Copy link

Expected Behavior

No timeout.

Current Behavior

Caused by: java.lang.IllegalStateException: com.nimbusds.jose.RemoteKeySourceException: Couldn't retrieve remote JWK set: Read timed out
	at org.springframework.security.oauth2.jwt.JwtDecoderProviderConfigurationUtils.getSignatureAlgorithms(JwtDecoderProviderConfigurationUtils.java:107)
	at org.springframework.security.oauth2.jwt.JwtDecoders.withProviderConfiguration(JwtDecoders.java:122)
	at org.springframework.security.oauth2.jwt.JwtDecoders.fromOidcIssuerLocation(JwtDecoders.java:66)

Context

I am using Spring Security 5.5.3

Our team set up some JWT Decoder by utilizing JwtDecoders like this:

@Bean
  JwtDecoder jwtDecoder() {
    final NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder)
        JwtDecoders.fromOidcIssuerLocation(issuer);

    final OAuth2TokenValidator<Jwt> audienceValidator = new AudienceValidator(apiAudience);
    final OAuth2TokenValidator<Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(issuer);
    final OAuth2TokenValidator<Jwt> withAudience = new DelegatingOAuth2TokenValidator<>(withIssuer, audienceValidator);

    jwtDecoder.setJwtValidator(withAudience);

    return jwtDecoder;
  }

In the current implementation, I see it is now trying to obtain signature algorithms and it possibly can cause timeout.

I already tried to look around, but the answer is not good enough. This similar discussion #4474 seems left hanging. This stackoverflow thread has hacky solution. This one also is not conclusive.

@andreas-trvlk andreas-trvlk added status: waiting-for-triage An issue we've not yet triaged type: enhancement A general enhancement labels Dec 15, 2021
@marcusdacoregio marcusdacoregio added in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 15, 2021
@jgrandja
Copy link
Contributor

jgrandja commented Jan 5, 2022

@andreas-trvlk Please see the reference doc on how to configure timeouts.

I'll close this as answered.

@vishal423
Copy link

@jgrandja, I believe you have overlooked the problem reported over here. JwtDecoders doesn't provide a way to specify the timeout and if you try to rewrite the custom JwtDecoders code, then, you will notice the underlying JwtDecoderProviderConfigurationUtils class has package visibility.

I think the problem reported over here and also in the linked JHipster issue comes from the below line of code. The current implementation doesn't specify the ResourceRetriever bean object as the 2nd constructor argument of RemoteJWKSet and thus internally defaults to DefaultResourceRetriever bean object with connection and read timeouts as 500ms.

    private static JwtDecoder withProviderConfiguration(Map<String, Object> configuration, String issuer) {
        ...
        RemoteJWKSet<SecurityContext> jwkSource = new RemoteJWKSet(url(jwkSetUri));
        ...
    }

Can we extend JwtDecoders class to provide a method to allow specification of RestOperations and ResourceRetriever as input parameters?

@jgrandja
Copy link
Contributor

@vishal423 Please see comment. There are no references to JwtDecoders?

I believe you have overlooked the problem reported over here. JwtDecoders doesn't provide a way to specify the timeout and if you try to rewrite the custom JwtDecoders code

If you link through to the referenced sample code, the solution is provided:

@Bean
public JwtDecoder jwtDecoder(RestTemplateBuilder builder) {
    RestOperations rest = builder
            .setConnectTimeout(Duration.ofSeconds(60))
            .setReadTimeout(Duration.ofSeconds(60))
            .build();

    NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwkSetUri(jwkSetUri).restOperations(rest).build();
    return jwtDecoder;
}

@vishal423
Copy link

@jgrandja, In the sample code, you are expected to have jwkSetUri to build the JwtDecoder, however, the issue raised is for JwtDecoders trying to create a JwtDecoder from oidc issuerUri using the fromOidcIssuerLocation factory method. Unless I missed something, you can't pass a timeout to that factory method.

@jgrandja
Copy link
Contributor

@vishal423 JwtDecoders does not fulfill all use cases, e.g. you cannot configure timeouts. It's designed as a utility for simple/convenient use cases. For more advanced use cases, e.g. configure timeouts, you need to explicitly create/configure the NimbusJwtDecoder as mentioned in previous comment.

@vishal423
Copy link

@jgrandja , I feel the default 500ms as connect/read timeout is too small in a low bandwidth usage scenario and we should update that to a more reasonable number.

I also tried to write custom JwtDecoders with configurable timeouts, however, noted that the underlying used JwtDecoderProviderConfigurationUtils class has package visibility. Can we change that to public to allow easy extension in such scenarios?

@jzheaux
Copy link
Contributor

jzheaux commented Jan 26, 2022

@vishal423 there are no plans to make the utils class public as it continues to be quite a bit in flux. Perhaps you'd be interested in #10309.

@ankit-donor360
Copy link

@jgrandja , I feel the default 500ms as connect/read timeout is too small in a low bandwidth usage scenario and we should update that to a more reasonable number.

I also tried to write custom JwtDecoders with configurable timeouts, however, noted that the underlying used JwtDecoderProviderConfigurationUtils class has package visibility. Can we change that to public to allow easy extension in such scenarios?

@vishal423 Did you find the solution? I am facing same issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

6 participants