From b5f1dd7db5ce1b4b8ac2c2e1a42107082715bc59 Mon Sep 17 00:00:00 2001 From: slam Date: Wed, 31 Aug 2022 12:17:51 +0800 Subject: [PATCH] #11754 - HttpSecurityDsl should support apply method --- .../config/annotation/web/HttpSecurityDsl.kt | 27 +++++++++++++ .../annotation/web/HttpSecurityDslTests.kt | 38 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/config/src/main/kotlin/org/springframework/security/config/annotation/web/HttpSecurityDsl.kt b/config/src/main/kotlin/org/springframework/security/config/annotation/web/HttpSecurityDsl.kt index 4433f7ed397..1593869e192 100644 --- a/config/src/main/kotlin/org/springframework/security/config/annotation/web/HttpSecurityDsl.kt +++ b/config/src/main/kotlin/org/springframework/security/config/annotation/web/HttpSecurityDsl.kt @@ -18,9 +18,11 @@ package org.springframework.security.config.annotation.web import org.springframework.context.ApplicationContext import org.springframework.security.authentication.AuthenticationManager +import org.springframework.security.config.annotation.SecurityConfigurerAdapter import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository +import org.springframework.security.web.DefaultSecurityFilterChain import org.springframework.security.web.util.matcher.RequestMatcher import org.springframework.util.ClassUtils import jakarta.servlet.Filter @@ -76,6 +78,31 @@ class HttpSecurityDsl(private val http: HttpSecurity, private val init: HttpSecu var authenticationManager: AuthenticationManager? = null + /** + * Applies a [SecurityConfigurerAdapter] to this [HttpSecurity] + * + * Example: + * + * ``` + * @Configuration + * @EnableWebSecurity + * class SecurityConfig : WebSecurityConfigurerAdapter() { + * + * override fun configure(http: HttpSecurity) { + * http { + * apply(CustomSecurityConfigurer()) + * } + * } + * } + * ``` + * + * @param configurer + * the [SecurityConfigurerAdapter] for further customizations + */ + fun > apply(configurer: C): C { + return this.http.apply(configurer) + } + /** * Allows configuring the [HttpSecurity] to only be invoked when matching the * provided pattern. diff --git a/config/src/test/kotlin/org/springframework/security/config/annotation/web/HttpSecurityDslTests.kt b/config/src/test/kotlin/org/springframework/security/config/annotation/web/HttpSecurityDslTests.kt index 2dc162ed48a..4173eee8381 100644 --- a/config/src/test/kotlin/org/springframework/security/config/annotation/web/HttpSecurityDslTests.kt +++ b/config/src/test/kotlin/org/springframework/security/config/annotation/web/HttpSecurityDslTests.kt @@ -30,7 +30,9 @@ import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.authentication.ProviderManager import org.springframework.security.authentication.TestingAuthenticationProvider import org.springframework.security.authentication.TestingAuthenticationToken +import org.springframework.security.config.Customizer import org.springframework.security.config.annotation.web.builders.HttpSecurity +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.test.SpringTestContext import org.springframework.security.config.test.SpringTestContextExtension @@ -516,4 +518,40 @@ class HttpSecurityDslTests { } class CustomFilter : UsernamePasswordAuthenticationFilter() + + @Test + fun `HTTP security when apply customer security configurer then custom filter added to filter chain`() { + this.spring.register(CustomSecurityConfigurerConfig::class.java).autowire() + + val filterChain = spring.context.getBean(FilterChainProxy::class.java) + val filterClasses: List> = filterChain.getFilters("/").map { it.javaClass } + + assertThat(filterClasses).contains( + CustomFilter::class.java + ) + } + @Configuration + @EnableWebSecurity + @EnableWebMvc + open class CustomSecurityConfigurerConfig { + @Bean + open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { + http { + apply(CustomSecurityConfigurer()).custom { + } + } + return http.build() + } + } + + class CustomSecurityConfigurer> : AbstractHttpConfigurer, H>() { + override fun configure(builder: H) { + builder.addFilterBefore(CustomFilter(), UsernamePasswordAuthenticationFilter::class.java) + } + + fun custom(configurer: Customizer>): CustomSecurityConfigurer { + configurer.customize(CustomSecurityConfigurer()) + return this + } + } }