Allow to set default securityContextRepository for each authentication mechanisms

Fixes gh-7249
This commit is contained in:
Eddú Meléndez
2019-08-17 15:21:35 -05:00
committed by Josh Cummings
parent 5e98b92273
commit 8773c7994f
4 changed files with 118 additions and 19 deletions

View File

@@ -26,11 +26,15 @@ import org.openqa.selenium.support.PageFactory;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.config.annotation.web.reactive.ServerHttpSecurityConfigurationBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.htmlunit.server.WebTestClientHtmlUnitDriverBuilder;
import org.springframework.security.test.web.reactive.server.WebTestClientBuilder;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.WebFilterChainProxy;
import org.springframework.security.web.server.authentication.RedirectServerAuthenticationSuccessHandler;
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
import org.springframework.security.web.server.csrf.CsrfToken;
import org.springframework.stereotype.Controller;
import org.springframework.test.web.reactive.server.WebTestClient;
@@ -44,12 +48,15 @@ import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.springframework.security.config.Customizer.withDefaults;
/**
* @author Rob Winch
* @author Eddú Meléndez
* @since 5.0
*/
public class FormLoginTests {
@@ -272,6 +279,50 @@ public class FormLoginTests {
verifyZeroInteractions(defaultAuthenticationManager);
}
@Test
public void formLoginSecurityContextRepository() {
ServerSecurityContextRepository defaultSecContextRepository = mock(ServerSecurityContextRepository.class);
ServerSecurityContextRepository formLoginSecContextRepository = mock(ServerSecurityContextRepository.class);
TestingAuthenticationToken token = new TestingAuthenticationToken("rob", "rob", "ROLE_USER");
given(defaultSecContextRepository.save(any(), any())).willReturn(Mono.empty());
given(defaultSecContextRepository.load(any())).willReturn(authentication(token));
given(formLoginSecContextRepository.save(any(), any())).willReturn(Mono.empty());
given(formLoginSecContextRepository.load(any())).willReturn(authentication(token));
SecurityWebFilterChain securityWebFilter = this.http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.securityContextRepository(defaultSecContextRepository)
.formLogin()
.securityContextRepository(formLoginSecContextRepository)
.and()
.build();
WebTestClient webTestClient = WebTestClientBuilder
.bindToWebFilters(securityWebFilter)
.build();
WebDriver driver = WebTestClientHtmlUnitDriverBuilder
.webTestClientSetup(webTestClient)
.build();
DefaultLoginPage loginPage = DefaultLoginPage.to(driver)
.assertAt();
HomePage homePage = loginPage.loginForm()
.username("user")
.password("password")
.submit(HomePage.class);
homePage.assertAt();
verify(defaultSecContextRepository, atLeastOnce()).load(any());
verify(formLoginSecContextRepository).save(any(), any());
}
public static class CustomLoginPage {
private WebDriver driver;
@@ -501,4 +552,10 @@ public class FormLoginTests {
+ "</html>");
}
}
Mono<SecurityContext> authentication(Authentication authentication) {
SecurityContext context = new SecurityContextImpl();
context.setAuthentication(authentication);
return Mono.just(context);
}
}

View File

@@ -428,6 +428,7 @@ public class OAuth2LoginTests {
ServerSecurityContextRepository securityContextRepository = config.securityContextRepository;
when(securityContextRepository.save(any(), any())).thenReturn(Mono.empty());
when(securityContextRepository.load(any())).thenReturn(authentication(token));
Map<String, Object> additionalParameters = new HashMap<>();
additionalParameters.put(OidcParameterNames.ID_TOKEN, "id-token");

View File

@@ -75,6 +75,7 @@ import org.springframework.security.web.server.authentication.HttpBasicServerAut
/**
* @author Rob Winch
* @author Eddú Meléndez
* @since 5.0
*/
@RunWith(MockitoJUnitRunner.class)
@@ -117,7 +118,6 @@ public class ServerHttpSecurityTests {
public void basic() {
given(this.authenticationManager.authenticate(any())).willReturn(Mono.just(new TestingAuthenticationToken("rob", "rob", "ROLE_USER", "ROLE_ADMIN")));
this.http.securityContextRepository(new WebSessionServerSecurityContextRepository());
this.http.httpBasic();
this.http.authenticationManager(this.authenticationManager);
ServerHttpSecurity.AuthorizeExchangeSpec authorize = this.http.authorizeExchange();
@@ -137,6 +137,30 @@ public class ServerHttpSecurityTests {
assertThat(result.getResponseCookies().getFirst("SESSION")).isNull();
}
@Test
public void basicWithGlobalWebSessionServerSecurityContextRepository() {
given(this.authenticationManager.authenticate(any())).willReturn(Mono.just(new TestingAuthenticationToken("rob", "rob", "ROLE_USER", "ROLE_ADMIN")));
this.http.securityContextRepository(new WebSessionServerSecurityContextRepository());
this.http.httpBasic();
this.http.authenticationManager(this.authenticationManager);
ServerHttpSecurity.AuthorizeExchangeSpec authorize = this.http.authorizeExchange();
authorize.anyExchange().authenticated();
WebTestClient client = buildClient();
EntityExchangeResult<String> result = client.get()
.uri("/")
.headers(headers -> headers.setBasicAuth("rob", "rob"))
.exchange()
.expectStatus().isOk()
.expectHeader().valueMatches(HttpHeaders.CACHE_CONTROL, ".+")
.expectBody(String.class).consumeWith(b -> assertThat(b.getResponseBody()).isEqualTo("ok"))
.returnResult();
assertThat(result.getResponseCookies().getFirst("SESSION")).isNotNull();
}
@Test
public void basicWhenNoCredentialsThenUnauthorized() {
this.http.authorizeExchange().anyExchange().authenticated();
@@ -256,7 +280,6 @@ public class ServerHttpSecurityTests {
public void basicWithAnonymous() {
given(this.authenticationManager.authenticate(any())).willReturn(Mono.just(new TestingAuthenticationToken("rob", "rob", "ROLE_USER", "ROLE_ADMIN")));
this.http.securityContextRepository(new WebSessionServerSecurityContextRepository());
this.http.httpBasic().and().anonymous();
this.http.authenticationManager(this.authenticationManager);
ServerHttpSecurity.AuthorizeExchangeSpec authorize = this.http.authorizeExchange();