From a55c3e4ab729832ba6192a6e43faf59fdff7f187 Mon Sep 17 00:00:00 2001 From: Anastasiia Losieva Date: Wed, 25 Mar 2020 22:45:49 +0100 Subject: [PATCH] Use jws-algorithm property in ReactiveOAuth2ResourceServerJwkConfiguration See gh-20681 --- ...eOAuth2ResourceServerJwkConfiguration.java | 10 +++++-- ...2ResourceServerAutoConfigurationTests.java | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java index f0241335600..d6bd29f015a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerJwkConfiguration.java @@ -31,6 +31,7 @@ import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity.OAuth2ResourceServerSpec; +import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm; import org.springframework.security.oauth2.jwt.JwtValidators; import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder; import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; @@ -45,6 +46,7 @@ import org.springframework.security.web.server.SecurityWebFilterChain; * @author Madhura Bhave * @author Artsiom Yudovin * @author HaiTao Zhang + * @author Anastasiia Losieva */ @Configuration(proxyBeanMethods = false) class ReactiveOAuth2ResourceServerJwkConfiguration { @@ -62,8 +64,9 @@ class ReactiveOAuth2ResourceServerJwkConfiguration { @Bean @ConditionalOnProperty(name = "spring.security.oauth2.resourceserver.jwt.jwk-set-uri") ReactiveJwtDecoder jwtDecoder() { - NimbusReactiveJwtDecoder nimbusReactiveJwtDecoder = new NimbusReactiveJwtDecoder( - this.properties.getJwkSetUri()); + NimbusReactiveJwtDecoder nimbusReactiveJwtDecoder = NimbusReactiveJwtDecoder + .withJwkSetUri(this.properties.getJwkSetUri()) + .jwsAlgorithm(SignatureAlgorithm.from(this.properties.getJwsAlgorithm())).build(); String issuerUri = this.properties.getIssuerUri(); if (issuerUri != null) { nimbusReactiveJwtDecoder.setJwtValidator(JwtValidators.createDefaultWithIssuer(issuerUri)); @@ -76,7 +79,8 @@ class ReactiveOAuth2ResourceServerJwkConfiguration { NimbusReactiveJwtDecoder jwtDecoderByPublicKeyValue() throws Exception { RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA") .generatePublic(new X509EncodedKeySpec(getKeySpec(this.properties.readPublicKey()))); - return NimbusReactiveJwtDecoder.withPublicKey(publicKey).build(); + return NimbusReactiveJwtDecoder.withPublicKey(publicKey) + .signatureAlgorithm(SignatureAlgorithm.from(this.properties.getJwsAlgorithm())).build(); } private byte[] getKeySpec(String keyValue) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java index 6a3cacf0aa9..0d3d259e09b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/oauth2/resource/reactive/ReactiveOAuth2ResourceServerAutoConfigurationTests.java @@ -20,10 +20,12 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.stream.Stream; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.nimbusds.jose.JWSAlgorithm; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import org.junit.jupiter.api.AfterEach; @@ -68,6 +70,7 @@ import static org.mockito.Mockito.mock; * @author Madhura Bhave * @author Artsiom Yudovin * @author HaiTao Zhang + * @author Anastasiia Losieva */ class ReactiveOAuth2ResourceServerAutoConfigurationTests { @@ -94,6 +97,31 @@ class ReactiveOAuth2ResourceServerAutoConfigurationTests { }); } + @SuppressWarnings("unchecked") + @Test + void autoConfigurationUsingJwkSetUriShouldConfigureResourceServerUsingJwsAlgorithm() { + this.contextRunner + .withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com", + "spring.security.oauth2.resourceserver.jwt.jws-algorithm=RS512") + .run((context) -> { + NimbusReactiveJwtDecoder nimbusReactiveJwtDecoder = context.getBean(NimbusReactiveJwtDecoder.class); + assertThat(nimbusReactiveJwtDecoder).extracting("jwtProcessor.arg$2") + .matches((algorithms) -> ((Set) algorithms).contains(JWSAlgorithm.RS512)); + }); + } + + @Test + void autoConfigurationUsingPublicKeyValueShouldConfigureResourceServerUsingJwsAlgorithm() { + this.contextRunner.withPropertyValues( + "spring.security.oauth2.resourceserver.jwt.public-key-location=classpath:public-key-location", + "spring.security.oauth2.resourceserver.jwt.jws-algorithm=RS384").run((context) -> { + NimbusReactiveJwtDecoder nimbusReactiveJwtDecoder = context.getBean(NimbusReactiveJwtDecoder.class); + assertThat(nimbusReactiveJwtDecoder) + .extracting("jwtProcessor.arg$1.jwsKeySelector.expectedJwsAlgorithm") + .isEqualTo(JWSAlgorithm.RS384); + }); + } + @Test void autoConfigurationShouldConfigureResourceServerUsingOidcIssuerUri() throws IOException { this.server = new MockWebServer();