Browse Source

AuthenticationWebFilter handle empty Authentication

Fixes: gh-5333
Rob Winch 7 years ago
parent
commit
d874c4954e

+ 6 - 5
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));

+ 21 - 0
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> 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());