Add AuthenticationManager to Kotlin ServerHttpSecurityDsl

Closes gh-10053
This commit is contained in:
Eleftheria Stein 2021-07-09 10:34:57 +02:00
parent 2809a3309b
commit 79054093c9
2 changed files with 43 additions and 1 deletions

View File

@ -16,6 +16,7 @@
package org.springframework.security.config.web.server package org.springframework.security.config.web.server
import org.springframework.security.authentication.ReactiveAuthenticationManager
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository
import org.springframework.security.web.server.SecurityWebFilterChain import org.springframework.security.web.server.SecurityWebFilterChain
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher
@ -57,10 +58,13 @@ operator fun ServerHttpSecurity.invoke(httpConfiguration: ServerHttpSecurityDsl.
* @author Eleftheria Stein * @author Eleftheria Stein
* @since 5.4 * @since 5.4
* @param init the configurations to apply to the provided [ServerHttpSecurity] * @param init the configurations to apply to the provided [ServerHttpSecurity]
* @property authenticationManager the default [ReactiveAuthenticationManager] to use
*/ */
@ServerSecurityMarker @ServerSecurityMarker
class ServerHttpSecurityDsl(private val http: ServerHttpSecurity, private val init: ServerHttpSecurityDsl.() -> Unit) { class ServerHttpSecurityDsl(private val http: ServerHttpSecurity, private val init: ServerHttpSecurityDsl.() -> Unit) {
var authenticationManager: ReactiveAuthenticationManager? = null
/** /**
* Allows configuring the [ServerHttpSecurity] to only be invoked when matching the * Allows configuring the [ServerHttpSecurity] to only be invoked when matching the
* provided [ServerWebExchangeMatcher]. * provided [ServerWebExchangeMatcher].
@ -630,6 +634,7 @@ class ServerHttpSecurityDsl(private val http: ServerHttpSecurity, private val in
*/ */
internal fun build(): SecurityWebFilterChain { internal fun build(): SecurityWebFilterChain {
init() init()
authenticationManager?.also { this.http.authenticationManager(authenticationManager) }
return this.http.build() return this.http.build()
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,9 @@
package org.springframework.security.config.web.server package org.springframework.security.config.web.server
import io.mockk.every
import io.mockk.mockkObject
import io.mockk.verify
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -23,6 +26,8 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.ApplicationContext import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
import org.springframework.http.HttpHeaders import org.springframework.http.HttpHeaders
import org.springframework.security.authentication.ReactiveAuthenticationManager
import org.springframework.security.authentication.TestingAuthenticationToken
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
import org.springframework.security.config.test.SpringTestRule import org.springframework.security.config.test.SpringTestRule
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter
@ -199,4 +204,36 @@ class ServerHttpSecurityDslTests {
class CustomWebFilter : WebFilter { class CustomWebFilter : WebFilter {
override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> = Mono.empty() override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> = Mono.empty()
} }
@Test
fun `authentication manager when configured in DSL then used`() {
this.spring.register(AuthenticationManagerConfig::class.java).autowire()
mockkObject(AuthenticationManagerConfig.AUTHENTICATION_MANAGER)
every {
AuthenticationManagerConfig.AUTHENTICATION_MANAGER.authenticate(any())
} returns Mono.just(TestingAuthenticationToken("user", "password", "ROLE_USER"))
this.client.get().uri("/").headers { headers ->
headers.setBasicAuth("user", "password")
}.exchange()
verify(exactly = 1) { AuthenticationManagerConfig.AUTHENTICATION_MANAGER.authenticate(any()) }
}
@EnableWebFlux
@EnableWebFluxSecurity
open class AuthenticationManagerConfig {
companion object {
val AUTHENTICATION_MANAGER: ReactiveAuthenticationManager = ReactiveAuthenticationManager { Mono.empty() }
}
@Bean
open fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
return http {
authenticationManager = AUTHENTICATION_MANAGER
authorizeExchange {
authorize(anyExchange, authenticated)
}
httpBasic { }
}
}
}
} }