diff --git a/web/src/main/java/org/springframework/security/web/server/authentication/AuthenticationWebFilter.java b/web/src/main/java/org/springframework/security/web/server/authentication/AuthenticationWebFilter.java index f8c5d2c910..bac0340579 100644 --- a/web/src/main/java/org/springframework/security/web/server/authentication/AuthenticationWebFilter.java +++ b/web/src/main/java/org/springframework/security/web/server/authentication/AuthenticationWebFilter.java @@ -17,17 +17,15 @@ package org.springframework.security.web.server.authentication; import java.util.function.Function; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.context.ReactiveSecurityContextHolder; -import reactor.core.publisher.Mono; - import org.springframework.security.authentication.ReactiveAuthenticationManager; import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; import org.springframework.security.core.context.SecurityContextImpl; import org.springframework.security.web.server.ServerHttpBasicAuthenticationConverter; import org.springframework.security.web.server.WebFilterExchange; -import org.springframework.security.web.server.context.ServerSecurityContextRepository; import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository; +import org.springframework.security.web.server.context.ServerSecurityContextRepository; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers; import org.springframework.util.Assert; @@ -35,6 +33,8 @@ import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; +import reactor.core.publisher.Mono; + /** * A {@link WebFilter} that performs authentication of a particular request. An outline of the logic: * @@ -97,6 +97,7 @@ public class AuthenticationWebFilter implements WebFilter { WebFilterChain chain, Authentication token) { WebFilterExchange webFilterExchange = new WebFilterExchange(exchange, chain); return this.authenticationManager.authenticate(token) + .switchIfEmpty(Mono.defer(() -> Mono.error(new IllegalStateException("No provider found for " + token.getClass())))) .flatMap(authentication -> onAuthenticationSuccess(authentication, webFilterExchange)) .onErrorResume(AuthenticationException.class, e -> this.authenticationFailureHandler .onAuthenticationFailure(webFilterExchange, e)); diff --git a/web/src/test/java/org/springframework/security/web/server/authentication/AuthenticationWebFilterTests.java b/web/src/test/java/org/springframework/security/web/server/authentication/AuthenticationWebFilterTests.java index be21393beb..b026040ef1 100644 --- a/web/src/test/java/org/springframework/security/web/server/authentication/AuthenticationWebFilterTests.java +++ b/web/src/test/java/org/springframework/security/web/server/authentication/AuthenticationWebFilterTests.java @@ -204,6 +204,27 @@ public class AuthenticationWebFilterTests { verifyZeroInteractions(this.failureHandler); } + @Test + public void filterWhenConvertAndAuthenticationEmptyThenServerError() { + Mono authentication = Mono.just(new TestingAuthenticationToken("test", "this", "ROLE_USER")); + when(this.authenticationConverter.apply(any())).thenReturn(authentication); + when(this.authenticationManager.authenticate(any())).thenReturn(Mono.empty()); + + WebTestClient client = WebTestClientBuilder + .bindToWebFilters(this.filter) + .build(); + + client + .get() + .uri("/") + .exchange() + .expectStatus().is5xxServerError() + .expectBody().isEmpty(); + + verify(this.securityContextRepository, never()).save(any(), any()); + verifyZeroInteractions(this.successHandler, this.failureHandler); + } + @Test public void filterWhenNotMatchAndConvertAndAuthenticationSuccessThenContinues() { this.filter.setRequiresAuthenticationMatcher(e -> ServerWebExchangeMatcher.MatchResult.notMatch());