Skip to content

Commit f71464b

Browse files
committed
Merge branch '3.5.x' into 4.0.x
Closes gh-50227
2 parents 6093fd4 + fab53cc commit f71464b

6 files changed

Lines changed: 71 additions & 22 deletions

File tree

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
3232

3333
import static org.assertj.core.api.Assertions.assertThat;
34+
import static org.mockito.Mockito.mock;
3435

3536
/**
3637
* Tests for {@link OAuth2AuthorizationServerJwtAutoConfiguration}.
@@ -96,7 +97,7 @@ static class TestJwtDecoderConfiguration {
9697

9798
@Bean
9899
JwtDecoder jwtDecoder() {
99-
return (token) -> null;
100+
return mock(JwtDecoder.class);
100101
}
101102

102103
}

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

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3434
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3535
import org.springframework.boot.context.properties.PropertyMapper;
36+
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
3637
import org.springframework.boot.security.oauth2.server.resource.autoconfigure.ConditionalOnIssuerLocationJwtDecoder;
3738
import org.springframework.boot.security.oauth2.server.resource.autoconfigure.ConditionalOnPublicKeyJwtDecoder;
3839
import org.springframework.boot.security.oauth2.server.resource.autoconfigure.OAuth2ResourceServerProperties;
@@ -58,6 +59,7 @@
5859
import org.springframework.security.web.server.SecurityWebFilterChain;
5960
import org.springframework.util.Assert;
6061
import org.springframework.util.CollectionUtils;
62+
import org.springframework.util.StringUtils;
6163

6264
/**
6365
* Configures a {@link ReactiveJwtDecoder} when a JWK Set URI, OpenID Connect Issuer URI
@@ -111,7 +113,12 @@ ReactiveJwtDecoder jwtDecoder(ObjectProvider<JwkSetUriReactiveJwtDecoderBuilderC
111113

112114
private void jwsAlgorithms(Set<SignatureAlgorithm> signatureAlgorithms) {
113115
for (String algorithm : this.properties.getJwsAlgorithms()) {
114-
signatureAlgorithms.add(SignatureAlgorithm.from(algorithm));
116+
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.from(algorithm);
117+
if (signatureAlgorithm == null) {
118+
throw new InvalidConfigurationPropertyValueException(
119+
"spring.security.oauth2.resourceserver.jwt.jws-algorithms", algorithm, "Unknown algorithm");
120+
}
121+
signatureAlgorithms.add(signatureAlgorithm);
115122
}
116123
}
117124

@@ -142,7 +149,7 @@ NimbusReactiveJwtDecoder jwtDecoderByPublicKeyValue() throws Exception {
142149
RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
143150
.generatePublic(new X509EncodedKeySpec(getKeySpec(this.properties.readPublicKey())));
144151
NimbusReactiveJwtDecoder jwtDecoder = NimbusReactiveJwtDecoder.withPublicKey(publicKey)
145-
.signatureAlgorithm(SignatureAlgorithm.from(exactlyOneAlgorithm()))
152+
.signatureAlgorithm(exactlyOneAlgorithm())
146153
.build();
147154
List<OAuth2TokenValidator<Jwt>> validators = getValidators();
148155
jwtDecoder.setJwtValidator(validators.isEmpty() ? JwtValidators.createDefault()
@@ -155,15 +162,18 @@ private byte[] getKeySpec(String keyValue) {
155162
return Base64.getMimeDecoder().decode(keyValue);
156163
}
157164

158-
private String exactlyOneAlgorithm() {
165+
private SignatureAlgorithm exactlyOneAlgorithm() {
159166
List<String> algorithms = this.properties.getJwsAlgorithms();
160-
int count = (algorithms != null) ? algorithms.size() : 0;
161-
if (count != 1) {
162-
throw new IllegalStateException(
163-
"Creating a JWT decoder using a public key requires exactly one JWS algorithm but " + count
164-
+ " were configured");
167+
Assert.state(algorithms != null && algorithms.size() == 1,
168+
() -> "Creating a JWT decoder using a public key requires exactly one JWS algorithm but "
169+
+ algorithms.size() + " were configured");
170+
SignatureAlgorithm algorithm = SignatureAlgorithm.from(algorithms.get(0));
171+
if (algorithm == null) {
172+
throw new InvalidConfigurationPropertyValueException(
173+
"spring.security.oauth2.resourceserver.jwt.jws-algorithms",
174+
StringUtils.collectionToCommaDelimitedString(algorithms), "Unknown algorithm");
165175
}
166-
return algorithms.get(0);
176+
return algorithm;
167177
}
168178

169179
@Bean

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

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3434
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3535
import org.springframework.boot.context.properties.PropertyMapper;
36+
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
3637
import org.springframework.boot.security.autoconfigure.web.servlet.ConditionalOnDefaultWebSecurity;
3738
import org.springframework.boot.security.oauth2.server.resource.autoconfigure.ConditionalOnIssuerLocationJwtDecoder;
3839
import org.springframework.boot.security.oauth2.server.resource.autoconfigure.ConditionalOnPublicKeyJwtDecoder;
@@ -57,6 +58,7 @@
5758
import org.springframework.security.web.SecurityFilterChain;
5859
import org.springframework.util.Assert;
5960
import org.springframework.util.CollectionUtils;
61+
import org.springframework.util.StringUtils;
6062

6163
import static org.springframework.security.config.Customizer.withDefaults;
6264

@@ -109,7 +111,12 @@ JwtDecoder jwtDecoderByJwkKeySetUri(ObjectProvider<JwkSetUriJwtDecoderBuilderCus
109111

110112
private void jwsAlgorithms(Set<SignatureAlgorithm> signatureAlgorithms) {
111113
for (String algorithm : this.properties.getJwsAlgorithms()) {
112-
signatureAlgorithms.add(SignatureAlgorithm.from(algorithm));
114+
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.from(algorithm);
115+
if (signatureAlgorithm == null) {
116+
throw new InvalidConfigurationPropertyValueException(
117+
"spring.security.oauth2.resourceserver.jwt.jws-algorithms", algorithm, "Unknown algorithm");
118+
}
119+
signatureAlgorithms.add(signatureAlgorithm);
113120
}
114121
}
115122

@@ -140,7 +147,7 @@ JwtDecoder jwtDecoderByPublicKeyValue() throws Exception {
140147
RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
141148
.generatePublic(new X509EncodedKeySpec(getKeySpec(this.properties.readPublicKey())));
142149
NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withPublicKey(publicKey)
143-
.signatureAlgorithm(SignatureAlgorithm.from(exactlyOneAlgorithm()))
150+
.signatureAlgorithm(exactlyOneAlgorithm())
144151
.build();
145152
List<OAuth2TokenValidator<Jwt>> validators = getValidators();
146153
jwtDecoder.setJwtValidator(validators.isEmpty() ? JwtValidators.createDefault()
@@ -153,15 +160,18 @@ private byte[] getKeySpec(String keyValue) {
153160
return Base64.getMimeDecoder().decode(keyValue);
154161
}
155162

156-
private String exactlyOneAlgorithm() {
163+
private SignatureAlgorithm exactlyOneAlgorithm() {
157164
List<String> algorithms = this.properties.getJwsAlgorithms();
158-
int count = (algorithms != null) ? algorithms.size() : 0;
159-
if (count != 1) {
160-
throw new IllegalStateException(
161-
"Creating a JWT decoder using a public key requires exactly one JWS algorithm but " + count
162-
+ " were configured");
165+
Assert.state(algorithms != null && algorithms.size() == 1,
166+
() -> "Creating a JWT decoder using a public key requires exactly one JWS algorithm but "
167+
+ algorithms.size() + " were configured");
168+
SignatureAlgorithm algorithm = SignatureAlgorithm.from(algorithms.get(0));
169+
if (algorithm == null) {
170+
throw new InvalidConfigurationPropertyValueException(
171+
"spring.security.oauth2.resourceserver.jwt.jws-algorithms",
172+
StringUtils.collectionToCommaDelimitedString(algorithms), "Unknown algorithm");
163173
}
164-
return algorithms.get(0);
174+
return algorithm;
165175
}
166176

167177
@Bean

module/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/JwtConverterCustomizationsArgumentsProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ public Stream<? extends Arguments> provideArguments(ParameterDeclarations parame
7272
.claim(customPrincipalClaim, customPrincipalValue);
7373
Jwt noAuthoritiesCustomizationsJwt = jwtBuilder.claim("scp", jwtScopes[0] + " " + jwtScopes[1]).build();
7474
Jwt customAuthoritiesDelimiterJwt = jwtBuilder.claim("scp", jwtScopes[0] + "~" + jwtScopes[1]).build();
75-
Jwt customAuthoritiesClaimJwt = jwtBuilder.claim("scp", null)
75+
Jwt customAuthoritiesClaimJwt = jwtBuilder.claim("scp", "value")
7676
.claim(customAuthoritiesClaim, jwtScopes[0] + " " + jwtScopes[1])
7777
.build();
78-
Jwt customAuthoritiesClaimAndDelimiterJwt = jwtBuilder.claim("scp", null)
78+
Jwt customAuthoritiesClaimAndDelimiterJwt = jwtBuilder.claim("scp", "value")
7979
.claim(customAuthoritiesClaim, jwtScopes[0] + "~" + jwtScopes[1])
8080
.build();
8181
String[] customPrefixAuthorities = { customPrefix + jwtScopes[0], customPrefix + jwtScopes[1] };

module/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,19 @@ void autoConfigurationUsingJwkSetUriShouldConfigureResourceServerUsingMultipleJw
183183
});
184184
}
185185

186+
@Test
187+
void autoConfigurationUsingJwkSetUriShouldFailIfJwsAlgorithmIsUnknown() {
188+
this.contextRunner
189+
.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com",
190+
"spring.security.oauth2.resourceserver.jwt.jws-algorithms=NOT_VALID")
191+
.run((context) -> {
192+
assertThat(context).hasFailed();
193+
assertThat(context.getStartupFailure())
194+
.hasRootCauseMessage("Property spring.security.oauth2.resourceserver.jwt.jws-algorithms with value "
195+
+ "'NOT_VALID' is invalid: Unknown algorithm");
196+
});
197+
}
198+
186199
@Test
187200
@WithPublicKeyResource
188201
void autoConfigurationUsingPublicKeyValueShouldConfigureResourceServerUsingSingleJwsAlgorithm() {

module/spring-boot-security-oauth2-resource-server/src/test/java/org/springframework/boot/security/oauth2/server/resource/autoconfigure/servlet/OAuth2ResourceServerAutoConfigurationTests.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import tools.jackson.databind.json.JsonMapper;
4848

4949
import org.springframework.boot.autoconfigure.AutoConfigurations;
50+
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
5051
import org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration;
5152
import org.springframework.boot.security.autoconfigure.actuate.web.servlet.ManagementWebSecurityAutoConfiguration;
5253
import org.springframework.boot.security.autoconfigure.web.servlet.ServletWebSecurityAutoConfiguration;
@@ -186,6 +187,19 @@ void autoConfigurationShouldConfigureResourceServerWithMultipleJwsAlgorithms() {
186187
});
187188
}
188189

190+
@Test
191+
void autoConfigurationUsingJwkSetUriShouldFailIfJwsAlgorithmIsUnknown() {
192+
this.contextRunner
193+
.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com",
194+
"spring.security.oauth2.resourceserver.jwt.jws-algorithms=NOT_VALID")
195+
.run((context) -> {
196+
assertThat(context).hasFailed();
197+
assertThat(context.getStartupFailure())
198+
.hasRootCauseMessage("Property spring.security.oauth2.resourceserver.jwt.jws-algorithms with value "
199+
+ "'NOT_VALID' is invalid: Unknown algorithm");
200+
});
201+
}
202+
189203
@Test
190204
@WithPublicKeyResource
191205
void autoConfigurationUsingPublicKeyValueShouldConfigureResourceServerUsingSingleJwsAlgorithm() {
@@ -331,7 +345,8 @@ void autoConfigurationShouldFailIfAlgorithmIsInvalid() {
331345
"spring.security.oauth2.resourceserver.jwt.jws-algorithms=NOT_VALID")
332346
.run((context) -> assertThat(context).hasFailed()
333347
.getFailure()
334-
.hasMessageContaining("signatureAlgorithm cannot be null"));
348+
.hasMessageContaining("Unknown algorithm")
349+
.hasRootCauseExactlyInstanceOf(InvalidConfigurationPropertyValueException.class));
335350
}
336351

337352
@Test

0 commit comments

Comments
 (0)