Describe the bug I have an oauth2 server running on keycloak http://localhost:8080/keycloak-service/ and configured multi-tenancy using this
JwtIssuerReactiveAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerReactiveAuthenticationManagerResolver
("http://localhost:8080/keycloak-service/realms/tenant1", "http://localhost:8080/keycloak-service/realms/tenant2");
http
.authorizeExchange(exchanges -> exchanges
.anyExchange().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2
.authenticationManagerResolver(authenticationManagerResolver)
);
However if the keycloak service is down initally, and a request has been sent to the controller, server will return 500 with this error on the console
java.lang.IllegalArgumentException: Unable to resolve the Configuration with the provided Issuer of "http://localhost:8080/keycloak-service/realms/tenant1"
at org.springframework.security.oauth2.jwt.JwtDecoderProviderConfigurationUtils.getConfiguration(JwtDecoderProviderConfigurationUtils.java:143)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Which is expected as the oauth server is down. However once the keycloak service back up, subsequent call to the controller will still show the same result
To Reproduce 1. Stop keycloak-service (oauth server) 2. Start spring boot project 3. Call controller 4. Returns 500 error, oauth server is down 5. Start keycloak-service (aouth server) 6. call controller again 7. it still return 500 error, even though oauth server is up
Expected behavior Expect step 7 above to show success instead of failure
Comment From: jzheaux
Thanks for the report, @Lzxe92.
I think this is because JwtIssuerReactiveAuthenticationManagerResolver is using Mono#cache. A better solution would likely be to use the version of Mono#cache that allows for specifying a TTL. In this case, I think specifying a TTL like so will address the issue:
.cache((manager) -> Duration.ofMillis(Long.MAX_VALUE), (ex) -> Duration.ZERO, () -> Duration.ZERO)
Are you able to provide a PR that makes the change and adds a test? Also, it would be helpful to have a test for JwtIssuerAuthenticationManagerResolver as well to ensure that this use case is addressed for both implementations.
Comment From: Lzxe92
Sure. I'll make a PR for this to help others.