Do not configure a ReactiveJmtDecoder without spring-webflux

This commit guards the creation of a ReactiveJwtDecoder with the
presence of Spring WebFlux. WebClient is used behind the scenes and
the sole presences of the authorization server and reactive types were
not precise enough.

Closes gh-49807
This commit is contained in:
Stéphane Nicoll
2026-03-27 11:11:22 +01:00
parent eea4e2c72f
commit 29b03edf6f
2 changed files with 13 additions and 0 deletions
@@ -31,6 +31,7 @@ import java.util.Set;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
@@ -53,6 +54,7 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
import org.springframework.security.oauth2.jwt.SupplierReactiveJwtDecoder;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.reactive.function.client.WebClient;
/**
* {@link Configuration @Configuration} for reactive JWT decoder beans.
@@ -67,6 +69,7 @@ import org.springframework.util.CollectionUtils;
* @author Phillip Webb
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(WebClient.class)
@ConditionalOnMissingBean(ReactiveJwtDecoder.class)
class ReactiveJwtDecoderConfiguration {
@@ -83,6 +83,7 @@ import org.springframework.security.oauth2.server.resource.authentication.Reacti
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.reactive.function.client.WebClient;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -300,6 +301,15 @@ class ReactiveOAuth2ResourceServerAutoConfigurationTests {
});
}
@Test
void autoConfigurationShouldBackOffIfWebClientIsNotAvailable() {
this.contextRunner.withClassLoader(new FilteredClassLoader(WebClient.class))
.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com")
.run((context) -> assertThat(context).hasNotFailed()
.doesNotHaveBean(NimbusReactiveJwtDecoder.class)
.doesNotHaveBean(ReactiveJwtDecoder.class));
}
@Test
void autoConfigurationShouldFailIfPublicKeyLocationDoesNotExist() {
this.contextRunner