I have to integrate form login based with recaptcha v3, so I also need recaptcha and action parameters to be extracted from the POST (to make the call to recaptcha service).
With current infrastructure it is necessary to do it manually (see snippet below), just add an option to ServerHttpSecurity
to configure it and use it:
AuthenticationWebFilter authenticationFilter = new AuthenticationWebFilter(this.authenticationManager);
authenticationFilter.setRequiresAuthenticationMatcher(this.requiresAuthenticationMatcher);
authenticationFilter.setAuthenticationFailureHandler(this.authenticationFailureHandler);
HERE ===> authenticationFilter.setAuthenticationConverter(new ServerFormLoginAuthenticationConverter()); <=== HERE
authenticationFilter.setAuthenticationSuccessHandler(this.authenticationSuccessHandler);
authenticationFilter.setSecurityContextRepository(this.securityContextRepository);
http.addFilterAt(authenticationFilter, SecurityWebFiltersOrder.FORM_LOGIN);
I use this snippet to change it (I have also a custom ReactiveAuthenticationManager
):
@Bean
fun securityWebFilterChain(
serverHttpSecurity: ServerHttpSecurity
): SecurityWebFilterChain = serverHttpSecurity
.formLogin()
...
.build().apply {
webFilters.filter {
it is AuthenticationWebFilter
}.toStream().forEach {
it as AuthenticationWebFilter
it.setServerAuthenticationConverter(RecaptchaV3ServerFormLoginAuthenticationConverter())
}
}
}
Comment From: rstoyanchev
This looks like an issue for https://github.com/spring-projects/spring-security. @rwinch are you able to move it if you agree?
Comment From: userquin
@rstoyanchev sorry to bother you:
Is this correct? I've never use reactor, I'm trying using kotlin coroutines on WebFilters and Authentication:
open class RecaptchaV3ReactiveAuthenticationManager(
var webClient: WebClient,
var reactiveUserDetailsService: ReactiveUserDetailsService,
val grecaptchaProperties: GrecaptchaProperties,
val userDetailsPasswordService: ReactiveUserDetailsPasswordService? = null,
var messages: MessageSourceAccessor = SpringSecurityMessageSource.getAccessor(),
var passwordEncoder: PasswordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder()
): ReactiveAuthenticationManager {
override fun authenticate(
authentication: Authentication
): Mono<Authentication> = mono(Dispatchers.Unconfined) {
doAuthenticate(authentication)
}
private suspend fun doAuthenticate(authentication: Authentication): Authentication {
val username = authentication.name
val credentials = authentication.credentials as RecaptchaV3LoginCredential
val user = retrieveUser(username).awaitFirstOrNull()
Comment From: userquin
Is there any chance that the SpringFramework folks would create the CoroutineWebFilter
and CoroutineAuthenticationManager
variants to allow using kotlin coroutines instead of WebFilter
and ReactiveAuthenticationManager
with reactor respectively ?
Comment From: sdeleuze
@userquin I had several requests already for a CoroutinesWebFilter
, please create an issue for that on Spring Framework side.
Comment From: rstoyanchev
As for the original issue, please create it in the Spring Security project.