diff --git a/config/src/main/kotlin/org/springframework/security/config/web/servlet/oauth2/resourceserver/JwtDsl.kt b/config/src/main/kotlin/org/springframework/security/config/web/servlet/oauth2/resourceserver/JwtDsl.kt index db99bf8d43..ce9d7a6912 100644 --- a/config/src/main/kotlin/org/springframework/security/config/web/servlet/oauth2/resourceserver/JwtDsl.kt +++ b/config/src/main/kotlin/org/springframework/security/config/web/servlet/oauth2/resourceserver/JwtDsl.kt @@ -35,9 +35,22 @@ import org.springframework.security.oauth2.jwt.JwtDecoder * JSON Web Key (JWK) URL */ class JwtDsl { + private var _jwtDecoder: JwtDecoder? = null + private var _jwkSetUri: String? = null + var jwtAuthenticationConverter: Converter? = null - var jwtDecoder: JwtDecoder? = null - var jwkSetUri: String? = null + var jwtDecoder: JwtDecoder? + get() = _jwtDecoder + set(value) { + _jwtDecoder = value + _jwkSetUri = null + } + var jwkSetUri: String? + get() = _jwkSetUri + set(value) { + _jwkSetUri = value + _jwtDecoder = null + } internal fun get(): (OAuth2ResourceServerConfigurer.JwtConfigurer) -> Unit { return { jwt -> diff --git a/config/src/test/kotlin/org/springframework/security/config/web/servlet/oauth2/resourceserver/JwtDslTests.kt b/config/src/test/kotlin/org/springframework/security/config/web/servlet/oauth2/resourceserver/JwtDslTests.kt index b168b37eb1..bb088954d5 100644 --- a/config/src/test/kotlin/org/springframework/security/config/web/servlet/oauth2/resourceserver/JwtDslTests.kt +++ b/config/src/test/kotlin/org/springframework/security/config/web/servlet/oauth2/resourceserver/JwtDslTests.kt @@ -25,10 +25,10 @@ import org.springframework.core.convert.converter.Converter import org.springframework.security.authentication.AbstractAuthenticationToken import org.springframework.security.authentication.TestingAuthenticationToken import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.config.web.servlet.invoke import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter import org.springframework.security.config.test.SpringTestRule +import org.springframework.security.config.web.servlet.invoke import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames import org.springframework.security.oauth2.jwt.Jwt import org.springframework.security.oauth2.jwt.JwtDecoder @@ -85,7 +85,7 @@ class JwtDslTests { } @Test - fun `opaque token when custom JWT authentication converter then converter used`() { + fun `JWT when custom JWT authentication converter then converter used`() { this.spring.register(CustomJwtAuthenticationConverterConfig::class.java).autowire() `when`(CustomJwtAuthenticationConverterConfig.DECODER.decode(anyString())).thenReturn( Jwt.withTokenValue("token") @@ -126,4 +126,41 @@ class JwtDslTests { return DECODER } } + + @Test + fun `JWT when custom JWT decoder set after jwkSetUri then decoder used`() { + this.spring.register(JwtDecoderAfterJwkSetUriConfig::class.java).autowire() + `when`(JwtDecoderAfterJwkSetUriConfig.DECODER.decode(anyString())).thenReturn( + Jwt.withTokenValue("token") + .header("alg", "none") + .claim(IdTokenClaimNames.SUB, "user") + .build()) + + this.mockMvc.get("/") { + header("Authorization", "Bearer token") + } + + verify(JwtDecoderAfterJwkSetUriConfig.DECODER).decode(any()) + } + + @EnableWebSecurity + open class JwtDecoderAfterJwkSetUriConfig : WebSecurityConfigurerAdapter() { + companion object { + var DECODER: JwtDecoder = mock(JwtDecoder::class.java) + } + + override fun configure(http: HttpSecurity) { + http { + authorizeRequests { + authorize(anyRequest, authenticated) + } + oauth2ResourceServer { + jwt { + jwkSetUri = "https://jwk-uri" + jwtDecoder = DECODER + } + } + } + } + } }