|
|
@ -32,6 +32,7 @@ import com.nimbusds.jose.JWSAlgorithm;
|
|
|
|
import jakarta.servlet.Filter;
|
|
|
|
import jakarta.servlet.Filter;
|
|
|
|
import okhttp3.mockwebserver.MockResponse;
|
|
|
|
import okhttp3.mockwebserver.MockResponse;
|
|
|
|
import okhttp3.mockwebserver.MockWebServer;
|
|
|
|
import okhttp3.mockwebserver.MockWebServer;
|
|
|
|
|
|
|
|
import org.assertj.core.api.InstanceOfAssertFactories;
|
|
|
|
import org.junit.jupiter.api.AfterEach;
|
|
|
|
import org.junit.jupiter.api.AfterEach;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
|
|
|
|
|
|
@ -54,6 +55,7 @@ import org.springframework.security.oauth2.jwt.JwtClaimValidator;
|
|
|
|
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
|
|
|
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
|
|
|
import org.springframework.security.oauth2.jwt.JwtIssuerValidator;
|
|
|
|
import org.springframework.security.oauth2.jwt.JwtIssuerValidator;
|
|
|
|
import org.springframework.security.oauth2.jwt.JwtTimestampValidator;
|
|
|
|
import org.springframework.security.oauth2.jwt.JwtTimestampValidator;
|
|
|
|
|
|
|
|
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
|
|
|
import org.springframework.security.oauth2.jwt.SupplierJwtDecoder;
|
|
|
|
import org.springframework.security.oauth2.jwt.SupplierJwtDecoder;
|
|
|
|
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
|
|
|
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
|
|
|
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider;
|
|
|
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider;
|
|
|
@ -119,20 +121,60 @@ class OAuth2ResourceServerAutoConfigurationTests {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@Test
|
|
|
|
void autoConfigurationShouldConfigureResourceServerWithJwsAlgorithm() {
|
|
|
|
void autoConfigurationShouldConfigureResourceServerWithSingleJwsAlgorithm() {
|
|
|
|
this.contextRunner
|
|
|
|
this.contextRunner
|
|
|
|
.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com",
|
|
|
|
.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com",
|
|
|
|
"spring.security.oauth2.resourceserver.jwt.jws-algorithm=RS384")
|
|
|
|
"spring.security.oauth2.resourceserver.jwt.jws-algorithms=RS384")
|
|
|
|
.run((context) -> {
|
|
|
|
.run((context) -> {
|
|
|
|
JwtDecoder jwtDecoder = context.getBean(JwtDecoder.class);
|
|
|
|
JwtDecoder jwtDecoder = context.getBean(JwtDecoder.class);
|
|
|
|
Object processor = ReflectionTestUtils.getField(jwtDecoder, "jwtProcessor");
|
|
|
|
Object processor = ReflectionTestUtils.getField(jwtDecoder, "jwtProcessor");
|
|
|
|
Object keySelector = ReflectionTestUtils.getField(processor, "jwsKeySelector");
|
|
|
|
Object keySelector = ReflectionTestUtils.getField(processor, "jwsKeySelector");
|
|
|
|
assertThat(keySelector).hasFieldOrPropertyWithValue("jwsAlgs",
|
|
|
|
assertThat(keySelector).extracting("jwsAlgs")
|
|
|
|
Collections.singleton(JWSAlgorithm.RS384));
|
|
|
|
.asInstanceOf(InstanceOfAssertFactories.collection(JWSAlgorithm.class))
|
|
|
|
|
|
|
|
.containsExactlyInAnyOrder(JWSAlgorithm.RS384);
|
|
|
|
|
|
|
|
assertThat(getBearerTokenFilter(context)).isNotNull();
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
|
|
|
void autoConfigurationShouldConfigureResourceServerWithMultipleJwsAlgorithms() {
|
|
|
|
|
|
|
|
this.contextRunner
|
|
|
|
|
|
|
|
.withPropertyValues("spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://jwk-set-uri.com",
|
|
|
|
|
|
|
|
"spring.security.oauth2.resourceserver.jwt.jws-algorithms=RS256, RS384, RS512")
|
|
|
|
|
|
|
|
.run((context) -> {
|
|
|
|
|
|
|
|
JwtDecoder jwtDecoder = context.getBean(JwtDecoder.class);
|
|
|
|
|
|
|
|
Object processor = ReflectionTestUtils.getField(jwtDecoder, "jwtProcessor");
|
|
|
|
|
|
|
|
Object keySelector = ReflectionTestUtils.getField(processor, "jwsKeySelector");
|
|
|
|
|
|
|
|
assertThat(keySelector).extracting("jwsAlgs")
|
|
|
|
|
|
|
|
.asInstanceOf(InstanceOfAssertFactories.collection(JWSAlgorithm.class))
|
|
|
|
|
|
|
|
.containsExactlyInAnyOrder(JWSAlgorithm.RS256, JWSAlgorithm.RS384, JWSAlgorithm.RS512);
|
|
|
|
assertThat(getBearerTokenFilter(context)).isNotNull();
|
|
|
|
assertThat(getBearerTokenFilter(context)).isNotNull();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
|
|
|
void autoConfigurationUsingPublicKeyValueShouldConfigureResourceServerUsingSingleJwsAlgorithm() {
|
|
|
|
|
|
|
|
this.contextRunner.withPropertyValues(
|
|
|
|
|
|
|
|
"spring.security.oauth2.resourceserver.jwt.public-key-location=classpath:public-key-location",
|
|
|
|
|
|
|
|
"spring.security.oauth2.resourceserver.jwt.jws-algorithms=RS384").run((context) -> {
|
|
|
|
|
|
|
|
NimbusJwtDecoder nimbusJwtDecoder = context.getBean(NimbusJwtDecoder.class);
|
|
|
|
|
|
|
|
assertThat(nimbusJwtDecoder).extracting("jwtProcessor.jwsKeySelector.expectedJWSAlg")
|
|
|
|
|
|
|
|
.isEqualTo(JWSAlgorithm.RS384);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
|
|
|
void autoConfigurationUsingPublicKeyValueWithMultipleJwsAlgorithmsShouldFail() {
|
|
|
|
|
|
|
|
this.contextRunner.withPropertyValues(
|
|
|
|
|
|
|
|
"spring.security.oauth2.resourceserver.jwt.public-key-location=classpath:public-key-location",
|
|
|
|
|
|
|
|
"spring.security.oauth2.resourceserver.jwt.jws-algorithms=RSA256,RS384").run((context) -> {
|
|
|
|
|
|
|
|
assertThat(context).hasFailed();
|
|
|
|
|
|
|
|
assertThat(context.getStartupFailure()).hasRootCauseMessage(
|
|
|
|
|
|
|
|
"Creating a JWT decoder using a public key requires exactly one JWS algorithm but 2 were "
|
|
|
|
|
|
|
|
+ "configured");
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@Test
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
void autoConfigurationShouldConfigureResourceServerUsingOidcIssuerUri() throws Exception {
|
|
|
|
void autoConfigurationShouldConfigureResourceServerUsingOidcIssuerUri() throws Exception {
|
|
|
|