1

My SpringBoot application has a WebFilter that works with the incoming request. The request is validated If the check is passed, then the authentication object is added to the context. If the check fails, further processing of the filter chain is aborted and a 401 code is set in response.

But in my case, the switchIfEmpty block is always called. Regardless of what the check method returned.

Please tell me what could be the problem?

class MyFilter : WebFilter {

        override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
            val validate: Mono<Boolean> = Mono.just(true) //function that validates an incoming request and returns a Mono<Boolean>. For example Mono.just(true)
            return validate
                .filter { it }
                .flatMap {
                    log.info("Token verification passed")
                    val auth = UsernamePasswordAuthenticationToken("user", "", listOf())//create an authentication object based on the request. For example, a user token
                    chain.filter(exchange)
                        .contextWrite(ReactiveSecurityContextHolder.withAuthentication(auth))
                }
                .switchIfEmpty {
                    Mono.defer {
                        log.warn("Token verification failed")
                        val response = exchange.response
                        response.statusCode = HttpStatus.UNAUTHORIZED
                        response.setComplete()
                    }
                }
        }
    }

P.S. Unfortunately, this answer did not help me.
Within MonoExtensions, the switchIfEmpty function already calls Mono.defer internally.

fun <T> Mono<T>.switchIfEmpty(s: () -> Mono<T>): Mono<T> = this.switchIfEmpty(Mono.defer { s() })
gearbase
  • 21
  • 3
  • 2
    It's because `chain.filter(exchange)` returns a `Mono` which is an empty Mono. If you want a non-empty Mono inside the flatMap, you can consider using `thenReturn` operator for example. – Martin Tarjányi Jun 26 '23 at 21:57
  • 1
    Either @MartinTarjányi suggestion, or just simplify. Instead of filter + flatMap + switchIfEmpty, just flatMap directly, and put validation condition inside it `if (validated) { /* continue filter chain */ } else { /* unauthorized */ }` – amanin Jun 27 '23 at 06:01
  • [@Martin Tarjányi](https://stackoverflow.com/users/6051176/martin-tarj%c3%a1nyi) Thank you! I thought it was `Mono.` However, I imagined that the `Mono` returned by `chain.filter(exchange)` is not equal to `Mono.empty()`, because that `Mono` has a signal that the filter chain has executed successfully. – gearbase Jun 27 '23 at 07:20
  • 1
    @amanin Thank you! I did just that. I needed to understand the reason why `switchIfEmpty` is always executed. – gearbase Jun 27 '23 at 07:23

0 Answers0