From 902fca65a448c7c23591a7e7c4dee16085c3ef87 Mon Sep 17 00:00:00 2001 From: Eleftheria Stein Date: Fri, 28 Aug 2020 11:48:55 +0200 Subject: [PATCH] Add authenticationManagerResolver to Kotlin DSL Closes gh-8981 --- .../web/servlet/OAuth2ResourceServerDsl.kt | 4 + .../servlet/OAuth2ResourceServerDslTests.kt | 74 +++++++++++++++++-- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/config/src/main/kotlin/org/springframework/security/config/web/servlet/OAuth2ResourceServerDsl.kt b/config/src/main/kotlin/org/springframework/security/config/web/servlet/OAuth2ResourceServerDsl.kt index 9473eba17a..d881c27f14 100644 --- a/config/src/main/kotlin/org/springframework/security/config/web/servlet/OAuth2ResourceServerDsl.kt +++ b/config/src/main/kotlin/org/springframework/security/config/web/servlet/OAuth2ResourceServerDsl.kt @@ -16,6 +16,7 @@ package org.springframework.security.config.web.servlet +import org.springframework.security.authentication.AuthenticationManagerResolver import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.web.servlet.oauth2.resourceserver.JwtDsl import org.springframework.security.config.web.servlet.oauth2.resourceserver.OpaqueTokenDsl @@ -23,6 +24,7 @@ import org.springframework.security.config.annotation.web.configurers.oauth2.ser import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver import org.springframework.security.web.AuthenticationEntryPoint import org.springframework.security.web.access.AccessDeniedHandler +import javax.servlet.http.HttpServletRequest /** * A Kotlin DSL to configure [HttpSecurity] OAuth 2.0 resource server support using @@ -42,6 +44,7 @@ class OAuth2ResourceServerDsl { var accessDeniedHandler: AccessDeniedHandler? = null var authenticationEntryPoint: AuthenticationEntryPoint? = null var bearerTokenResolver: BearerTokenResolver? = null + var authenticationManagerResolver: AuthenticationManagerResolver? = null private var jwt: ((OAuth2ResourceServerConfigurer.JwtConfigurer) -> Unit)? = null private var opaqueToken: ((OAuth2ResourceServerConfigurer.OpaqueTokenConfigurer) -> Unit)? = null @@ -105,6 +108,7 @@ class OAuth2ResourceServerDsl { accessDeniedHandler?.also { oauth2ResourceServer.accessDeniedHandler(accessDeniedHandler) } authenticationEntryPoint?.also { oauth2ResourceServer.authenticationEntryPoint(authenticationEntryPoint) } bearerTokenResolver?.also { oauth2ResourceServer.bearerTokenResolver(bearerTokenResolver) } + authenticationManagerResolver?.also { oauth2ResourceServer.authenticationManagerResolver(authenticationManagerResolver) } jwt?.also { oauth2ResourceServer.jwt(jwt) } opaqueToken?.also { oauth2ResourceServer.opaqueToken(opaqueToken) } } diff --git a/config/src/test/kotlin/org/springframework/security/config/web/servlet/OAuth2ResourceServerDslTests.kt b/config/src/test/kotlin/org/springframework/security/config/web/servlet/OAuth2ResourceServerDslTests.kt index 2ac4326244..0cb5c08b35 100644 --- a/config/src/test/kotlin/org/springframework/security/config/web/servlet/OAuth2ResourceServerDslTests.kt +++ b/config/src/test/kotlin/org/springframework/security/config/web/servlet/OAuth2ResourceServerDslTests.kt @@ -16,11 +16,15 @@ package org.springframework.security.config.web.servlet +import org.assertj.core.api.Assertions import org.junit.Rule import org.junit.Test import org.mockito.Mockito.* +import org.springframework.beans.factory.BeanCreationException import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Bean +import org.springframework.security.authentication.AuthenticationManager +import org.springframework.security.authentication.AuthenticationManagerResolver import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter @@ -28,11 +32,13 @@ import org.springframework.security.config.test.SpringTestRule import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames.SUB import org.springframework.security.oauth2.jwt.Jwt import org.springframework.security.oauth2.jwt.JwtDecoder +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver import org.springframework.security.web.AuthenticationEntryPoint import org.springframework.security.web.access.AccessDeniedHandler import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.get +import javax.servlet.http.HttpServletRequest /** * Tests for [OAuth2ResourceServerDsl] @@ -47,6 +53,11 @@ class OAuth2ResourceServerDslTests { @Autowired lateinit var mockMvc: MockMvc + private val JWT: Jwt = Jwt.withTokenValue("token") + .header("alg", "none") + .claim(SUB, "user") + .build() + @Test fun `oauth2Resource server when custom entry point then entry point used`() { this.spring.register(EntryPointConfig::class.java).autowire() @@ -116,11 +127,7 @@ class OAuth2ResourceServerDslTests { @Test fun `oauth2Resource server when custom access denied handler then handler used`() { this.spring.register(AccessDeniedHandlerConfig::class.java).autowire() - `when`(AccessDeniedHandlerConfig.DECODER.decode(anyString())).thenReturn( - Jwt.withTokenValue("token") - .header("alg", "none") - .claim(SUB, "user") - .build()) + `when`(AccessDeniedHandlerConfig.DECODER.decode(anyString())).thenReturn(JWT) this.mockMvc.get("/") { header("Authorization", "Bearer token") @@ -153,4 +160,61 @@ class OAuth2ResourceServerDslTests { return DECODER } } + + @Test + fun `oauth2Resource server when custom authentication manager resolver then resolver used`() { + this.spring.register(AuthenticationManagerResolverConfig::class.java).autowire() + `when`(AuthenticationManagerResolverConfig.RESOLVER.resolve(any())).thenReturn( + AuthenticationManager { + JwtAuthenticationToken(JWT) + } + ) + + this.mockMvc.get("/") { + header("Authorization", "Bearer token") + } + + verify(AuthenticationManagerResolverConfig.RESOLVER).resolve(any()) + } + + @EnableWebSecurity + open class AuthenticationManagerResolverConfig : WebSecurityConfigurerAdapter() { + companion object { + var RESOLVER: AuthenticationManagerResolver<*> = mock(AuthenticationManagerResolver::class.java) + } + + override fun configure(http: HttpSecurity) { + http { + authorizeRequests { + authorize(anyRequest, authenticated) + } + oauth2ResourceServer { + authenticationManagerResolver = RESOLVER as AuthenticationManagerResolver + } + } + } + } + + @Test + fun `oauth2Resource server when custom authentication manager resolver and opaque then exception`() { + Assertions.assertThatExceptionOfType(BeanCreationException::class.java) + .isThrownBy { spring.register(AuthenticationManagerResolverAndOpaqueConfig::class.java).autowire() } + .withMessageContaining("authenticationManagerResolver") + } + + @EnableWebSecurity + open class AuthenticationManagerResolverAndOpaqueConfig : WebSecurityConfigurerAdapter() { + override fun configure(http: HttpSecurity) { + http { + authorizeRequests { + authorize(anyRequest, authenticated) + } + oauth2ResourceServer { + authenticationManagerResolver = mock(AuthenticationManagerResolver::class.java) + as AuthenticationManagerResolver + opaqueToken { } + } + } + } + } }