Skip to content

Commit 3233341

Browse files
committed
Improve class conditions on auth server JWT auto-config
Prior to this change, introspection of the auto-configuration could fail due to insufficient protection against missing classes. This commit introduces an extra class-level check for Nimbus's JWKSource which ensures that the auto-configuration backs off if nimbus-jose-jwt has been excluded. It also introduces an inner-class for the case where spring-security-oauth2-jose is not on the classpath. This ensures that the method defining the jwtDecoder bean does not cause an introspection failure when JwtDecoder is missing. Closes gh-45177
1 parent 4cfc3b0 commit 3233341

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfiguration.java

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@
3636
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
3737
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
3838
import org.springframework.context.annotation.Bean;
39+
import org.springframework.context.annotation.Configuration;
3940
import org.springframework.context.annotation.Role;
4041
import org.springframework.security.oauth2.jwt.JwtDecoder;
4142
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
@@ -49,17 +50,10 @@
4950
* @since 3.1.0
5051
*/
5152
@AutoConfiguration(after = UserDetailsServiceAutoConfiguration.class)
52-
@ConditionalOnClass(OAuth2Authorization.class)
53+
@ConditionalOnClass({ OAuth2Authorization.class, JWKSource.class })
5354
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
5455
public class OAuth2AuthorizationServerJwtAutoConfiguration {
5556

56-
@Bean
57-
@ConditionalOnClass(JwtDecoder.class)
58-
@ConditionalOnMissingBean
59-
JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
60-
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
61-
}
62-
6357
@Bean
6458
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
6559
@ConditionalOnMissingBean
@@ -92,4 +86,16 @@ private static KeyPair generateRsaKey() {
9286
return keyPair;
9387
}
9488

89+
@Configuration(proxyBeanMethods = false)
90+
@ConditionalOnClass(JwtDecoder.class)
91+
static class JwtDecoderConfiguration {
92+
93+
@Bean
94+
@ConditionalOnMissingBean
95+
JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
96+
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
97+
}
98+
99+
}
100+
95101
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/server/servlet/OAuth2AuthorizationServerJwtAutoConfigurationTests.java

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,15 +43,22 @@ class OAuth2AuthorizationServerJwtAutoConfigurationTests {
4343
.withConfiguration(AutoConfigurations.of(OAuth2AuthorizationServerJwtAutoConfiguration.class));
4444

4545
@Test
46-
void autoConfigurationConditionalOnClassOauth2Authorization() {
46+
void autoConfigurationConditionalOnClassOAuth2Authorization() {
4747
this.contextRunner.withClassLoader(new FilteredClassLoader(OAuth2Authorization.class))
4848
.run((context) -> assertThat(context).doesNotHaveBean(OAuth2AuthorizationServerJwtAutoConfiguration.class));
4949
}
5050

51+
@Test
52+
void autoConfigurationConditionalOnClassJWKSource() {
53+
this.contextRunner.withClassLoader(new FilteredClassLoader(JWKSource.class))
54+
.run((context) -> assertThat(context).doesNotHaveBean(OAuth2AuthorizationServerJwtAutoConfiguration.class));
55+
}
56+
5157
@Test
5258
void jwtDecoderConditionalOnClassJwtDecoder() {
5359
this.contextRunner.withClassLoader(new FilteredClassLoader(JwtDecoder.class))
54-
.run((context) -> assertThat(context).doesNotHaveBean("jwtDecoder"));
60+
.run((context) -> assertThat(context).hasSingleBean(OAuth2AuthorizationServerJwtAutoConfiguration.class)
61+
.doesNotHaveBean("jwtDecoder"));
5562
}
5663

5764
@Test

0 commit comments

Comments
 (0)