Skip to content

Commit 93c0029

Browse files
committed
Provide @ConditionalOn… annotations for all concrete conditions
1 parent 457ed37 commit 93c0029

File tree

20 files changed

+244
-44
lines changed

20 files changed

+244
-44
lines changed

buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheck.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import com.tngtech.archunit.core.domain.JavaClass.Predicates;
3737
import com.tngtech.archunit.core.domain.JavaClasses;
3838
import com.tngtech.archunit.core.domain.JavaMethod;
39+
import com.tngtech.archunit.core.domain.JavaModifier;
3940
import com.tngtech.archunit.core.domain.JavaParameter;
4041
import com.tngtech.archunit.core.domain.JavaType;
4142
import com.tngtech.archunit.core.domain.properties.CanBeAnnotated;
@@ -97,7 +98,7 @@ public ArchitectureCheck() {
9798
noClassesShouldLoadResourcesUsingResourceUtils(), noClassesShouldCallStringToUpperCaseWithoutLocale(),
9899
noClassesShouldCallStringToLowerCaseWithoutLocale(),
99100
conditionalOnMissingBeanShouldNotSpecifyOnlyATypeThatIsTheSameAsMethodReturnType(),
100-
enumSourceShouldNotSpecifyOnlyATypeThatIsTheSameAsMethodParameterType());
101+
enumSourceShouldNotSpecifyOnlyATypeThatIsTheSameAsMethodParameterType(), conditionsShouldNotBePublic());
101102
getRules().addAll(getProhibitObjectsRequireNonNull()
102103
.map((prohibit) -> prohibit ? noClassesShouldCallObjectsRequireNonNull() : Collections.emptyList()));
103104
getRuleDescriptions().set(getRules().map((rules) -> rules.stream().map(ArchRule::getDescription).toList()));
@@ -254,6 +255,20 @@ private ArchRule noClassesShouldCallURLEncoderWithStringEncoding() {
254255
.because("java.net.URLEncoder.encode(String s, Charset charset) should be used instead");
255256
}
256257

258+
private ArchRule conditionsShouldNotBePublic() {
259+
String springBootCondition = "org.springframework.boot.autoconfigure.condition.SpringBootCondition";
260+
return ArchRuleDefinition.noClasses()
261+
.that()
262+
.areAssignableTo(springBootCondition)
263+
.and()
264+
.doNotHaveModifier(JavaModifier.ABSTRACT)
265+
.and()
266+
.areNotAnnotatedWith(Deprecated.class)
267+
.should()
268+
.bePublic()
269+
.allowEmptyShould(true);
270+
}
271+
257272
private ArchRule noClassesShouldCallURLDecoderWithStringEncoding() {
258273
return ArchRuleDefinition.noClasses()
259274
.should()

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnPropertyListCondition.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 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.
@@ -34,7 +34,7 @@
3434
* @author Stephane Nicoll
3535
* @since 2.0.5
3636
*/
37-
public class OnPropertyListCondition extends SpringBootCondition {
37+
public abstract class OnPropertyListCondition extends SpringBootCondition {
3838

3939
private static final Bindable<List<String>> STRING_LIST = Bindable.listOf(String.class);
4040

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/ClientsConfiguredCondition.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 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.
@@ -35,7 +35,10 @@
3535
*
3636
* @author Madhura Bhave
3737
* @since 2.1.0
38+
* @deprecated since 3.5.0 for removal in 3.7.0 in favor of
39+
* {@link ConditionalOnOAuth2ClientRegistrationConfigured @ConditionalOnOAuth2ClientRegistrationConfigured}
3840
*/
41+
@Deprecated(since = "3.5.0", forRemoval = true)
3942
public class ClientsConfiguredCondition extends SpringBootCondition {
4043

4144
private static final Bindable<Map<String, OAuth2ClientProperties.Registration>> STRING_REGISTRATION_MAP = Bindable
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2012-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.security.oauth2.client;
18+
19+
import java.lang.annotation.Documented;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
import org.springframework.context.annotation.Conditional;
26+
27+
/**
28+
* Condition that matches if any {@code spring.security.oauth2.client.registration}
29+
* properties are defined.
30+
*
31+
* @author Andy Wilkinson
32+
* @since 3.5.0
33+
*/
34+
@SuppressWarnings("removal")
35+
@Retention(RetentionPolicy.RUNTIME)
36+
@Target({ ElementType.TYPE, ElementType.METHOD })
37+
@Documented
38+
@Conditional(ClientsConfiguredCondition.class)
39+
public @interface ConditionalOnOAuth2ClientRegistrationConfigured {
40+
41+
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientConfigurations.java

+3-4
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.
@@ -22,11 +22,10 @@
2222
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2323
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2424
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
25-
import org.springframework.boot.autoconfigure.security.oauth2.client.ClientsConfiguredCondition;
25+
import org.springframework.boot.autoconfigure.security.oauth2.client.ConditionalOnOAuth2ClientRegistrationConfigured;
2626
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;
2727
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesMapper;
2828
import org.springframework.context.annotation.Bean;
29-
import org.springframework.context.annotation.Conditional;
3029
import org.springframework.context.annotation.Configuration;
3130
import org.springframework.security.config.web.server.ServerHttpSecurity;
3231
import org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService;
@@ -48,7 +47,7 @@
4847
class ReactiveOAuth2ClientConfigurations {
4948

5049
@Configuration(proxyBeanMethods = false)
51-
@Conditional(ClientsConfiguredCondition.class)
50+
@ConditionalOnOAuth2ClientRegistrationConfigured
5251
@ConditionalOnMissingBean(ReactiveClientRegistrationRepository.class)
5352
static class ReactiveClientRegistrationRepositoryConfiguration {
5453

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientRegistrationRepositoryConfiguration.java

+3-4
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.
@@ -20,12 +20,11 @@
2020
import java.util.List;
2121

2222
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
23-
import org.springframework.boot.autoconfigure.security.oauth2.client.ClientsConfiguredCondition;
23+
import org.springframework.boot.autoconfigure.security.oauth2.client.ConditionalOnOAuth2ClientRegistrationConfigured;
2424
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;
2525
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesMapper;
2626
import org.springframework.boot.context.properties.EnableConfigurationProperties;
2727
import org.springframework.context.annotation.Bean;
28-
import org.springframework.context.annotation.Conditional;
2928
import org.springframework.context.annotation.Configuration;
3029
import org.springframework.security.oauth2.client.registration.ClientRegistration;
3130
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
@@ -39,7 +38,7 @@
3938
*/
4039
@Configuration(proxyBeanMethods = false)
4140
@EnableConfigurationProperties(OAuth2ClientProperties.class)
42-
@Conditional(ClientsConfiguredCondition.class)
41+
@ConditionalOnOAuth2ClientRegistrationConfigured
4342
class OAuth2ClientRegistrationRepositoryConfiguration {
4443

4544
@Bean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2012-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.security.oauth2.resource;
18+
19+
import java.lang.annotation.Documented;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
import org.springframework.context.annotation.Conditional;
26+
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
27+
28+
/**
29+
* Condition that matches when an {@link NimbusJwtDecoder#withIssuerLocation
30+
* issuer-location-based JWT decoder} should be used.
31+
*
32+
* @author Andy Wilkinson
33+
* @since 3.5.0
34+
*/
35+
@SuppressWarnings("removal")
36+
@Retention(RetentionPolicy.RUNTIME)
37+
@Target({ ElementType.TYPE, ElementType.METHOD })
38+
@Documented
39+
@Conditional(IssuerUriCondition.class)
40+
public @interface ConditionalOnIssuerLocationJwtDecoder {
41+
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2012-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.security.oauth2.resource;
18+
19+
import java.lang.annotation.Documented;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
import org.springframework.context.annotation.Conditional;
26+
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
27+
28+
/**
29+
* Condition that matches when a {@link NimbusJwtDecoder#withPublicKey public-key-based
30+
* JWT decoder} should be used.
31+
*
32+
* @author Andy Wilkinson
33+
* @since 3.5.0
34+
*/
35+
@SuppressWarnings("removal")
36+
@Retention(RetentionPolicy.RUNTIME)
37+
@Target({ ElementType.TYPE, ElementType.METHOD })
38+
@Documented
39+
@Conditional(KeyValueCondition.class)
40+
public @interface ConditionalOnPublicKeyJwtDecoder {
41+
42+
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/IssuerUriCondition.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 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.
@@ -30,18 +30,21 @@
3030
*
3131
* @author Artsiom Yudovin
3232
* @since 2.1.0
33+
* @deprecated since 3.5.0 for removal in 3.7.0 in favor of
34+
* {@link ConditionalOnIssuerLocationJwtDecoder @ConditionalOnIssuerLocationJwtDecoder}
3335
*/
36+
@Deprecated(since = "3.5.0", forRemoval = true)
3437
public class IssuerUriCondition extends SpringBootCondition {
3538

3639
@Override
3740
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
3841
ConditionMessage.Builder message = ConditionMessage.forCondition("OpenID Connect Issuer URI Condition");
3942
Environment environment = context.getEnvironment();
4043
String issuerUri = environment.getProperty("spring.security.oauth2.resourceserver.jwt.issuer-uri");
41-
String jwkSetUri = environment.getProperty("spring.security.oauth2.resourceserver.jwt.jwk-set-uri");
4244
if (!StringUtils.hasText(issuerUri)) {
4345
return ConditionOutcome.noMatch(message.didNotFind("issuer-uri property").atAll());
4446
}
47+
String jwkSetUri = environment.getProperty("spring.security.oauth2.resourceserver.jwt.jwk-set-uri");
4548
if (StringUtils.hasText(jwkSetUri)) {
4649
return ConditionOutcome.noMatch(message.found("jwk-set-uri property").items(jwkSetUri));
4750
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/KeyValueCondition.java

+5-2
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.
@@ -29,7 +29,10 @@
2929
*
3030
* @author Madhura Bhave
3131
* @since 2.2.0
32+
* @deprecated since 3.5.0 for removal in 3.7.0 in favor of
33+
* {@link ConditionalOnPublicKeyJwtDecoder @ConditionalOnPublicKeyJwtDecoder}
3234
*/
35+
@Deprecated(since = "3.5.0", forRemoval = true)
3336
public class KeyValueCondition extends SpringBootCondition {
3437

3538
@Override
@@ -41,11 +44,11 @@ public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeM
4144
if (!StringUtils.hasText(publicKeyLocation)) {
4245
return ConditionOutcome.noMatch(message.didNotFind("public-key-location property").atAll());
4346
}
44-
String issuerUri = environment.getProperty("spring.security.oauth2.resourceserver.jwt.issuer-uri");
4547
String jwkSetUri = environment.getProperty("spring.security.oauth2.resourceserver.jwt.jwk-set-uri");
4648
if (StringUtils.hasText(jwkSetUri)) {
4749
return ConditionOutcome.noMatch(message.found("jwk-set-uri property").items(jwkSetUri));
4850
}
51+
String issuerUri = environment.getProperty("spring.security.oauth2.resourceserver.jwt.issuer-uri");
4952
if (StringUtils.hasText(issuerUri)) {
5053
return ConditionOutcome.noMatch(message.found("issuer-uri property").items(issuerUri));
5154
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
3131
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3232
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
33-
import org.springframework.boot.autoconfigure.security.oauth2.resource.IssuerUriCondition;
34-
import org.springframework.boot.autoconfigure.security.oauth2.resource.KeyValueCondition;
33+
import org.springframework.boot.autoconfigure.security.oauth2.resource.ConditionalOnIssuerLocationJwtDecoder;
34+
import org.springframework.boot.autoconfigure.security.oauth2.resource.ConditionalOnPublicKeyJwtDecoder;
3535
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
3636
import org.springframework.boot.context.properties.PropertyMapper;
3737
import org.springframework.context.annotation.Bean;
@@ -130,7 +130,7 @@ private boolean nullSafeDisjoint(List<String> c1, List<String> c2) {
130130
}
131131

132132
@Bean
133-
@Conditional(KeyValueCondition.class)
133+
@ConditionalOnPublicKeyJwtDecoder
134134
NimbusReactiveJwtDecoder jwtDecoderByPublicKeyValue() throws Exception {
135135
RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
136136
.generatePublic(new X509EncodedKeySpec(getKeySpec(this.properties.readPublicKey())));
@@ -158,7 +158,7 @@ private String exactlyOneAlgorithm() {
158158
}
159159

160160
@Bean
161-
@Conditional(IssuerUriCondition.class)
161+
@ConditionalOnIssuerLocationJwtDecoder
162162
SupplierReactiveJwtDecoder jwtDecoderByIssuerUri(
163163
ObjectProvider<JwkSetUriReactiveJwtDecoderBuilderCustomizer> customizers) {
164164
return new SupplierReactiveJwtDecoder(() -> {

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/servlet/OAuth2ResourceServerJwtConfiguration.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3232
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3333
import org.springframework.boot.autoconfigure.security.ConditionalOnDefaultWebSecurity;
34-
import org.springframework.boot.autoconfigure.security.oauth2.resource.IssuerUriCondition;
35-
import org.springframework.boot.autoconfigure.security.oauth2.resource.KeyValueCondition;
34+
import org.springframework.boot.autoconfigure.security.oauth2.resource.ConditionalOnIssuerLocationJwtDecoder;
35+
import org.springframework.boot.autoconfigure.security.oauth2.resource.ConditionalOnPublicKeyJwtDecoder;
3636
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
3737
import org.springframework.boot.context.properties.PropertyMapper;
3838
import org.springframework.context.annotation.Bean;
@@ -129,7 +129,7 @@ private boolean nullSafeDisjoint(List<String> c1, List<String> c2) {
129129
}
130130

131131
@Bean
132-
@Conditional(KeyValueCondition.class)
132+
@ConditionalOnPublicKeyJwtDecoder
133133
JwtDecoder jwtDecoderByPublicKeyValue() throws Exception {
134134
RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
135135
.generatePublic(new X509EncodedKeySpec(getKeySpec(this.properties.readPublicKey())));
@@ -157,7 +157,7 @@ private String exactlyOneAlgorithm() {
157157
}
158158

159159
@Bean
160-
@Conditional(IssuerUriCondition.class)
160+
@ConditionalOnIssuerLocationJwtDecoder
161161
SupplierJwtDecoder jwtDecoderByIssuerUri(ObjectProvider<JwkSetUriJwtDecoderBuilderCustomizer> customizers) {
162162
return new SupplierJwtDecoder(() -> {
163163
String issuerUri = this.properties.getIssuerUri();

0 commit comments

Comments
 (0)