Add authenticationSuccessHandler to Reactive Resource Server Kotlin DSL

Signed-off-by: Josh Cummings <[email protected]>
This commit is contained in:
Josh Cummings
2026-09-01 18:14:07 -07:00
parent 6eb7ef6e6d
commit 3070c96594
2 changed files with 47 additions and 0 deletions
@@ -20,6 +20,7 @@ import org.springframework.security.authentication.ReactiveAuthenticationManager
import org.springframework.security.web.server.ServerAuthenticationEntryPoint
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler
import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler
import org.springframework.web.server.ServerWebExchange
@@ -35,6 +36,8 @@ import org.springframework.web.server.ServerWebExchange
* @property bearerTokenConverter the [ServerAuthenticationConverter] to use for requests authenticating with
* Bearer Tokens.
* @property authenticationManagerResolver the [ReactiveAuthenticationManagerResolver] to use.
* @property authenticationSuccessHandler the [ServerAuthenticationSuccessHandler] to use after
* authentication success.
*/
@ServerSecurityMarker
class ServerOAuth2ResourceServerDsl {
@@ -43,6 +46,7 @@ class ServerOAuth2ResourceServerDsl {
var authenticationEntryPoint: ServerAuthenticationEntryPoint? = null
var bearerTokenConverter: ServerAuthenticationConverter? = null
var authenticationManagerResolver: ReactiveAuthenticationManagerResolver<ServerWebExchange>? = null
var authenticationSuccessHandler: ServerAuthenticationSuccessHandler? = null
private var jwt: ((ServerHttpSecurity.OAuth2ResourceServerSpec.JwtSpec) -> Unit)? = null
private var opaqueToken: ((ServerHttpSecurity.OAuth2ResourceServerSpec.OpaqueTokenSpec) -> Unit)? = null
@@ -115,6 +119,7 @@ class ServerOAuth2ResourceServerDsl {
authenticationEntryPoint?.also { oauth2ResourceServer.authenticationEntryPoint(authenticationEntryPoint) }
bearerTokenConverter?.also { oauth2ResourceServer.bearerTokenConverter(bearerTokenConverter) }
authenticationManagerResolver?.also { oauth2ResourceServer.authenticationManagerResolver(authenticationManagerResolver!!) }
authenticationSuccessHandler?.also { oauth2ResourceServer.authenticationSuccessHandler(authenticationSuccessHandler) }
jwt?.also { oauth2ResourceServer.jwt(jwt) }
opaqueToken?.also { oauth2ResourceServer.opaqueToken(opaqueToken) }
}
@@ -17,6 +17,7 @@
package org.springframework.security.config.web.server
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.verify
import org.junit.jupiter.api.Test
@@ -37,6 +38,7 @@ import org.springframework.security.web.server.SecurityWebFilterChain
import org.springframework.security.web.server.WebFilterExchange
import org.springframework.security.web.server.authentication.HttpStatusServerEntryPoint
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler
import org.springframework.security.web.server.authorization.HttpStatusServerAccessDeniedHandler
import org.springframework.test.web.reactive.server.WebTestClient
import org.springframework.web.reactive.config.EnableWebFlux
@@ -183,6 +185,46 @@ class ServerOAuth2ResourceServerDslTests {
}
@Test
fun `request when custom authentication success handler then success handler used`() {
this.spring.register(AuthenticationSuccessHandlerConfig::class.java).autowire()
every {
AuthenticationSuccessHandlerConfig.SUCCESS_HANDLER.onAuthenticationSuccess(any(), any())
} returns Mono.empty()
this.client.get()
.uri("/")
.headers { it.setBearerAuth(validJwt) }
.exchange()
verify(exactly = 1) { AuthenticationSuccessHandlerConfig.SUCCESS_HANDLER.onAuthenticationSuccess(any(), any()) }
}
@Configuration
@EnableWebFluxSecurity
@EnableWebFlux
open class AuthenticationSuccessHandlerConfig {
companion object {
val SUCCESS_HANDLER: ServerAuthenticationSuccessHandler = mockk()
}
@Bean
open fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
return http {
authorizeExchange {
authorize(anyExchange, authenticated)
}
oauth2ResourceServer {
authenticationSuccessHandler = SUCCESS_HANDLER
jwt {
publicKey = publicKey()
}
}
}
}
}
@Test
fun `request when custom bearer token converter configured then custom converter used`() {
this.spring.register(BearerTokenConverterConfig::class.java).autowire()