Introduced ReactiveAuthenticationManagerResolver

Suitable for multi-tenant reactive applications needing to branch
authentication strategies based on request details.
This commit is contained in:
Rafiullah Hamedy
2019-05-11 18:42:06 -04:00
committed by Josh Cummings
parent e0e66c62fc
commit f6ed1db702
5 changed files with 205 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,8 +23,10 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import reactor.core.publisher.Mono;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.ReactiveAuthenticationManagerResolver;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.test.web.reactive.server.WebTestClientBuilder;
@@ -40,6 +42,7 @@ import static org.mockito.Mockito.*;
/**
* @author Rob Winch
* @author Rafiullah Hamedy
* @since 5.0
*/
@RunWith(MockitoJUnitRunner.class)
@@ -54,6 +57,8 @@ public class AuthenticationWebFilterTests {
private ServerAuthenticationFailureHandler failureHandler;
@Mock
private ServerSecurityContextRepository securityContextRepository;
@Mock
private ReactiveAuthenticationManagerResolver<ServerHttpRequest> authenticationManagerResolver;
private AuthenticationWebFilter filter;
@@ -85,6 +90,25 @@ public class AuthenticationWebFilterTests {
assertThat(result.getResponseCookies()).isEmpty();
}
@Test
public void filterWhenAuthenticationManagerResolverDefaultsAndNoAuthenticationThenContinues() {
this.filter = new AuthenticationWebFilter(this.authenticationManagerResolver);
WebTestClient client = WebTestClientBuilder
.bindToWebFilters(this.filter)
.build();
EntityExchangeResult<String> result = client.get()
.uri("/")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).consumeWith(b -> assertThat(b.getResponseBody()).isEqualTo("ok"))
.returnResult();
verifyZeroInteractions(this.authenticationManagerResolver);
assertThat(result.getResponseCookies()).isEmpty();
}
@Test
public void filterWhenDefaultsAndAuthenticationSuccessThenContinues() {
when(this.authenticationManager.authenticate(any())).thenReturn(Mono.just(new TestingAuthenticationToken("test", "this", "ROLE")));
@@ -106,6 +130,29 @@ public class AuthenticationWebFilterTests {
assertThat(result.getResponseCookies()).isEmpty();
}
@Test
public void filterWhenAuthenticationManagerResolverDefaultsAndAuthenticationSuccessThenContinues() {
when(this.authenticationManager.authenticate(any())).thenReturn(Mono.just(new TestingAuthenticationToken("test", "this", "ROLE")));
when(this.authenticationManagerResolver.resolve(any())).thenReturn(Mono.just(this.authenticationManager));
this.filter = new AuthenticationWebFilter(this.authenticationManagerResolver);
WebTestClient client = WebTestClientBuilder
.bindToWebFilters(this.filter)
.build();
EntityExchangeResult<String> result = client
.get()
.uri("/")
.headers(headers -> headers.setBasicAuth("test", "this"))
.exchange()
.expectStatus().isOk()
.expectBody(String.class).consumeWith(b -> assertThat(b.getResponseBody()).isEqualTo("ok"))
.returnResult();
assertThat(result.getResponseCookies()).isEmpty();
}
@Test
public void filterWhenDefaultsAndAuthenticationFailThenUnauthorized() {
when(this.authenticationManager.authenticate(any())).thenReturn(Mono.error(new BadCredentialsException("failed")));
@@ -127,6 +174,29 @@ public class AuthenticationWebFilterTests {
assertThat(result.getResponseCookies()).isEmpty();
}
@Test
public void filterWhenAuthenticationManagerResolverDefaultsAndAuthenticationFailThenUnauthorized() {
when(this.authenticationManager.authenticate(any())).thenReturn(Mono.error(new BadCredentialsException("failed")));
when(this.authenticationManagerResolver.resolve(any())).thenReturn(Mono.just(this.authenticationManager));
this.filter = new AuthenticationWebFilter(this.authenticationManagerResolver);
WebTestClient client = WebTestClientBuilder
.bindToWebFilters(this.filter)
.build();
EntityExchangeResult<Void> result = client
.get()
.uri("/")
.headers(headers -> headers.setBasicAuth("test", "this"))
.exchange()
.expectStatus().isUnauthorized()
.expectHeader().valueMatches("WWW-Authenticate", "Basic realm=\"Realm\"")
.expectBody().isEmpty();
assertThat(result.getResponseCookies()).isEmpty();
}
@Test
public void filterWhenConvertEmptyThenOk() {
when(this.authenticationConverter.convert(any())).thenReturn(Mono.empty());