You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using one-time token login in reactive mode, with the simplest possible configuration, any GET call to / (curl http://localhost:8080/) or any non-spring-security-managed endpoint prints the following message to the console:
2025-01-21T15:25:12.601+01:00 ERROR 54059 --- [ parallel-7] o.s.w.s.adapter.HttpWebHandlerAdapter : [5e1343e8-3] Error [java.lang.UnsupportedOperationException] for HTTP GET "/", but ServerHttpResponse already committed (200 OK)
But no error or stack-trace.
Reactive stack trace in HttpWebHandlerAdapter:
java.lang.UnsupportedOperationException
at org.springframework.http.ReadOnlyHttpHeaders.set(ReadOnlyHttpHeaders.java:112)
Suppressed: The stacktrace has been enhanced by Reactor, refer to additional information below:
Assembly trace from producer [reactor.core.publisher.MonoFlatMap] :
reactor.core.publisher.Mono.flatMap(Mono.java:3179)
org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:134)
Error has been observed at the following site(s):
*________Mono.flatMap ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:134)
|_ Mono.doOnDiscard ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:140)
|_ checkpoint ⇢ Handler wf.garnier.experiments.ott.OttApplication$OttController#index() [DispatcherHandler]
|_ Mono.onErrorResume ⇢ at org.springframework.web.reactive.DispatcherHandler.lambda$handleResultMono$7(DispatcherHandler.java:176)
*________Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.lambda$handleResultMono$6(DispatcherHandler.java:177)
*________Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.handleResultMono(DispatcherHandler.java:172)
*________Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.handle(DispatcherHandler.java:154)
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
*___________Mono.then ⇢ at org.springframework.security.web.server.authentication.logout.LogoutWebFilter.filter(LogoutWebFilter.java:63)
*__Mono.switchIfEmpty ⇢ at org.springframework.security.web.server.authentication.logout.LogoutWebFilter.filter(LogoutWebFilter.java:63)
|_ Mono.map ⇢ at org.springframework.security.web.server.authentication.logout.LogoutWebFilter.filter(LogoutWebFilter.java:64)
|_ Mono.flatMap ⇢ at org.springframework.security.web.server.authentication.logout.LogoutWebFilter.filter(LogoutWebFilter.java:65)
|_ Mono.flatMap ⇢ at org.springframework.security.web.server.authentication.logout.LogoutWebFilter.filter(LogoutWebFilter.java:66)
|_ checkpoint ⇢ org.springframework.security.web.server.authentication.logout.LogoutWebFilter [DefaultWebFilterChain]
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
*________Mono.flatMap ⇢ at org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter.filter(ServerRequestCacheWebFilter.java:41)
|_ checkpoint ⇢ org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter [DefaultWebFilterChain]
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
|_ checkpoint ⇢ org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain]
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
*___________Mono.then ⇢ at org.springframework.security.web.server.ui.OneTimeTokenSubmitPageGeneratingWebFilter.filter(OneTimeTokenSubmitPageGeneratingWebFilter.java:56)
*__Mono.switchIfEmpty ⇢ at org.springframework.security.web.server.ui.OneTimeTokenSubmitPageGeneratingWebFilter.filter(OneTimeTokenSubmitPageGeneratingWebFilter.java:56)
|_ Mono.flatMap ⇢ at org.springframework.security.web.server.ui.OneTimeTokenSubmitPageGeneratingWebFilter.filter(OneTimeTokenSubmitPageGeneratingWebFilter.java:57)
|_ checkpoint ⇢ org.springframework.security.web.server.ui.OneTimeTokenSubmitPageGeneratingWebFilter [DefaultWebFilterChain]
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
*___________Mono.then ⇢ at org.springframework.security.web.server.authentication.ott.GenerateOneTimeTokenWebFilter.filter(GenerateOneTimeTokenWebFilter.java:64)
*__Mono.switchIfEmpty ⇢ at org.springframework.security.web.server.authentication.ott.GenerateOneTimeTokenWebFilter.filter(GenerateOneTimeTokenWebFilter.java:64)
|_ Mono.flatMap ⇢ at org.springframework.security.web.server.authentication.ott.GenerateOneTimeTokenWebFilter.filter(GenerateOneTimeTokenWebFilter.java:65)
|_ Mono.flatMap ⇢ at org.springframework.security.web.server.authentication.ott.GenerateOneTimeTokenWebFilter.filter(GenerateOneTimeTokenWebFilter.java:66)
|_ checkpoint ⇢ org.springframework.security.web.server.authentication.ott.GenerateOneTimeTokenWebFilter [DefaultWebFilterChain]
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
*___________Mono.then ⇢ at org.springframework.security.web.server.authentication.AuthenticationWebFilter.filter(AuthenticationWebFilter.java:114)
*__Mono.switchIfEmpty ⇢ at org.springframework.security.web.server.authentication.AuthenticationWebFilter.filter(AuthenticationWebFilter.java:114)
|_ Mono.flatMap ⇢ at org.springframework.security.web.server.authentication.AuthenticationWebFilter.filter(AuthenticationWebFilter.java:115)
|_ Mono.onErrorResume ⇢ at org.springframework.security.web.server.authentication.AuthenticationWebFilter.filter(AuthenticationWebFilter.java:116)
|_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
|_ Mono.contextWrite ⇢ at org.springframework.security.web.server.context.ReactorContextWebFilter.filter(ReactorContextWebFilter.java:48)
|_ checkpoint ⇢ org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain]
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
*__________Mono.defer ⇢ at org.springframework.security.web.server.csrf.CsrfWebFilter.continueFilterChain(CsrfWebFilter.java:148)
*___________Mono.then ⇢ at org.springframework.security.web.server.csrf.CsrfWebFilter.filter(CsrfWebFilter.java:126)
*__Mono.switchIfEmpty ⇢ at org.springframework.security.web.server.csrf.CsrfWebFilter.filter(CsrfWebFilter.java:126)
|_ Mono.onErrorResume ⇢ at org.springframework.security.web.server.csrf.CsrfWebFilter.filter(CsrfWebFilter.java:127)
|_ checkpoint ⇢ org.springframework.security.web.server.csrf.CsrfWebFilter [DefaultWebFilterChain]
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
|_ checkpoint ⇢ org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain]
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
|_ Mono.contextWrite ⇢ at org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter.filter(ServerHttpSecurity.java:4047)
|_ checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
*________Mono.flatMap ⇢ at org.springframework.security.web.server.WebFilterChainProxy.filterFirewalledExchange(WebFilterChainProxy.java:78)
*________Mono.flatMap ⇢ at org.springframework.security.web.server.WebFilterChainProxy.filter(WebFilterChainProxy.java:65)
|_ Mono.onErrorResume ⇢ at org.springframework.security.web.server.WebFilterChainProxy.filter(WebFilterChainProxy.java:66)
|_ checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
*__________Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:106)
|_ Mono.doOnError ⇢ at org.springframework.web.server.handler.ExceptionHandlingWebHandler.handle(ExceptionHandlingWebHandler.java:84)
|_ Mono.onErrorResume ⇢ at org.springframework.web.server.handler.ExceptionHandlingWebHandler.handle(ExceptionHandlingWebHandler.java:85)
|_ Mono.doOnError ⇢ at org.springframework.web.server.handler.ExceptionHandlingWebHandler.handle(ExceptionHandlingWebHandler.java:84)
|_ Mono.onErrorResume ⇢ at org.springframework.web.server.handler.ExceptionHandlingWebHandler.handle(ExceptionHandlingWebHandler.java:85)
|_ Mono.doOnError ⇢ at org.springframework.web.server.handler.ExceptionHandlingWebHandler.handle(ExceptionHandlingWebHandler.java:84)
|_ Mono.onErrorResume ⇢ at org.springframework.web.server.handler.ExceptionHandlingWebHandler.handle(ExceptionHandlingWebHandler.java:85)
|_ Mono.doOnSuccess ⇢ at org.springframework.web.server.adapter.HttpWebHandlerAdapter.handle(HttpWebHandlerAdapter.java:299)
*__________Mono.error ⇢ at org.springframework.web.server.handler.ExceptionHandlingWebHandler$CheckpointInsertingHandler.handle(ExceptionHandlingWebHandler.java:106)
|_ checkpoint ⇢ HTTP GET "/" [ExceptionHandlingWebHandler]
*__________Mono.error ⇢ at org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler.handle(AbstractErrorWebExceptionHandler.java:293)
*__________Mono.error ⇢ at org.springframework.web.server.handler.ResponseStatusExceptionHandler.handle(ResponseStatusExceptionHandler.java:68)
To Reproduce
Simple project with spring-webflux + spring-security, and the simplest possible OTT configuration:
Describe the bug
Using one-time token login in reactive mode, with the simplest possible configuration, any GET call to
/
(curl http://localhost:8080/
) or any non-spring-security-managed endpoint prints the following message to the console:But no error or stack-trace.
Reactive stack trace in HttpWebHandlerAdapter:
To Reproduce
Simple project with spring-webflux + spring-security, and the simplest possible OTT configuration:
the try to reach any non-spring security endpoint, e.g.
curl http://localhost:8080/
Analysis
GenerateOneTimeTokenWebFilter
triggers a double execution of the filter chain through two.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
.The following configuration:
Prints in the console:
Using
.addFilterBefore(new LoggingFilter(), SecurityWebFiltersOrder.ONE_TIME_TOKEN)
instead of registering it after only prints the success case.The text was updated successfully, but these errors were encountered: