HttpSecurityDsl should support apply method

Closes gh-11754
This commit is contained in:
slam 2022-08-31 12:17:51 +08:00 committed by Steve Riesenberg
parent 355ef21117
commit 45bbd86f7e
No known key found for this signature in database
GPG Key ID: 5F311AB48A55D521
2 changed files with 74 additions and 3 deletions

View File

@ -18,9 +18,11 @@ package org.springframework.security.config.web.servlet
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 javax.servlet.Filter
@ -75,6 +77,35 @@ 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 {
*
* @Bean
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
* http {
* apply(CustomSecurityConfigurer<HttpSecurity>()) {
* customProperty = "..."
* }
* }
* return http.build()
* }
* }
* ```
*
* @param configurer
* the [SecurityConfigurerAdapter] for further customizations
*/
fun <C : SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity>> apply(configurer: C, configuration: C.() -> Unit = { }): C {
return this.http.apply(configurer).apply(configuration)
}
/**
* Allows configuring the [HttpSecurity] to only be invoked when matching the
* provided pattern.

View File

@ -22,6 +22,8 @@ import io.mockk.verify
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@ -30,9 +32,11 @@ 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.annotation.web.HttpSecurityBuilder
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
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer
import org.springframework.security.config.test.SpringTestContext
import org.springframework.security.config.test.SpringTestContextExtension
import org.springframework.security.core.userdetails.User
@ -40,6 +44,7 @@ import org.springframework.security.core.userdetails.UserDetailsService
import org.springframework.security.provisioning.InMemoryUserDetailsManager
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic
import org.springframework.security.web.FilterChainProxy
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter
import org.springframework.security.web.server.header.ContentTypeOptionsServerHttpHeadersWriter
@ -53,9 +58,6 @@ import org.springframework.test.web.servlet.post
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.web.servlet.config.annotation.EnableWebMvc
import javax.servlet.Filter
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import org.springframework.security.web.SecurityFilterChain
/**
* Tests for [HttpSecurityDsl]
@ -483,4 +485,42 @@ class HttpSecurityDslTests {
}
class CustomFilter : UsernamePasswordAuthenticationFilter()
@Test
fun `HTTP security when apply custom 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<Class<out Filter>> = 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<HttpSecurity>()) {
filter = CustomFilter()
}
}
return http.build()
}
}
class CustomSecurityConfigurer<H : HttpSecurityBuilder<H>> : AbstractHttpConfigurer<CustomSecurityConfigurer<H>, H>() {
var filter: Filter? = null
override fun init(builder: H) {
filter = filter ?: UsernamePasswordAuthenticationFilter()
}
override fun configure(builder: H) {
builder.addFilterBefore(CustomFilter(), UsernamePasswordAuthenticationFilter::class.java)
}
}
}