Merge branch '5.8.x'

Closes gh-12133
This commit is contained in:
Josh Cummings
2022-11-02 15:49:18 -06:00
7 changed files with 199 additions and 13 deletions

View File

@@ -51,6 +51,7 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.ReactiveAuthenticationManagerResolver;
import org.springframework.security.authentication.TestingAuthenticationToken;
@@ -73,6 +74,7 @@ import org.springframework.security.oauth2.server.resource.introspection.Reactiv
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.HttpStatusServerEntryPoint;
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
import org.springframework.security.web.server.authorization.HttpStatusServerAccessDeniedHandler;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.bind.annotation.GetMapping;
@@ -347,6 +349,25 @@ public class OAuth2ResourceServerSpecTests {
// @formatter:on
}
@Test
public void getWhenUsingCustomAuthenticationFailureHandlerThenUsesIsAccordingly() {
this.spring.register(CustomAuthenticationFailureHandlerConfig.class).autowire();
ServerAuthenticationFailureHandler handler = this.spring.getContext()
.getBean(ServerAuthenticationFailureHandler.class);
ReactiveAuthenticationManager authenticationManager = this.spring.getContext()
.getBean(ReactiveAuthenticationManager.class);
given(authenticationManager.authenticate(any()))
.willReturn(Mono.error(() -> new BadCredentialsException("bad")));
given(handler.onAuthenticationFailure(any(), any())).willReturn(Mono.empty());
// @formatter:off
this.client.get()
.headers((headers) -> headers.setBearerAuth(this.messageReadToken))
.exchange()
.expectStatus().isOk();
// @formatter:on
verify(handler).onAuthenticationFailure(any(), any());
}
@Test
public void postWhenSignedThenReturnsOk() {
this.spring.register(PublicKeyConfig.class, RootController.class).autowire();
@@ -903,6 +924,35 @@ public class OAuth2ResourceServerSpecTests {
}
@Configuration
@EnableWebFlux
@EnableWebFluxSecurity
static class CustomAuthenticationFailureHandlerConfig {
@Bean
SecurityWebFilterChain springSecurity(ServerHttpSecurity http) {
// @formatter:off
http
.authorizeExchange((authorize) -> authorize.anyExchange().authenticated())
.oauth2ResourceServer((oauth2) -> oauth2
.authenticationFailureHandler(authenticationFailureHandler())
.jwt((jwt) -> jwt.authenticationManager(authenticationManager()))
);
// @formatter:on
return http.build();
}
@Bean
ReactiveAuthenticationManager authenticationManager() {
return mock(ReactiveAuthenticationManager.class);
}
@Bean
ServerAuthenticationFailureHandler authenticationFailureHandler() {
return mock(ServerAuthenticationFailureHandler.class);
}
}
@EnableWebFlux
@EnableWebFluxSecurity
static class CustomBearerTokenServerAuthenticationConverter {

View File

@@ -35,6 +35,7 @@ import reactor.test.publisher.TestPublisher;
import org.springframework.http.HttpStatus;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.config.annotation.web.reactive.ServerHttpSecurityConfigurationBuilder;
@@ -57,6 +58,7 @@ import org.springframework.security.web.server.WebFilterChainProxy;
import org.springframework.security.web.server.authentication.AnonymousAuthenticationWebFilterTests;
import org.springframework.security.web.server.authentication.HttpBasicServerAuthenticationEntryPoint;
import org.springframework.security.web.server.authentication.HttpStatusServerEntryPoint;
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
import org.springframework.security.web.server.authentication.ServerX509AuthenticationConverter;
import org.springframework.security.web.server.authentication.logout.DelegatingServerLogoutHandler;
import org.springframework.security.web.server.authentication.logout.LogoutWebFilter;
@@ -218,6 +220,27 @@ public class ServerHttpSecurityTests {
verify(authenticationEntryPoint).commence(any(), any());
}
@Test
public void basicWhenCustomAuthenticationFailureHandlerThenUses() {
ReactiveAuthenticationManager authenticationManager = mock(ReactiveAuthenticationManager.class);
ServerAuthenticationFailureHandler authenticationFailureHandler = mock(
ServerAuthenticationFailureHandler.class);
this.http.httpBasic().authenticationFailureHandler(authenticationFailureHandler);
this.http.httpBasic().authenticationManager(authenticationManager);
this.http.authorizeExchange().anyExchange().authenticated();
given(authenticationManager.authenticate(any()))
.willReturn(Mono.error(() -> new BadCredentialsException("bad")));
given(authenticationFailureHandler.onAuthenticationFailure(any(), any())).willReturn(Mono.empty());
WebTestClient client = buildClient();
// @formatter:off
client.get().uri("/")
.headers((headers) -> headers.setBasicAuth("user", "password"))
.exchange()
.expectStatus().isOk();
// @formatter:on
verify(authenticationFailureHandler).onAuthenticationFailure(any(), any());
}
@Test
public void buildWhenServerWebExchangeFromContextThenFound() {
SecurityWebFilterChain filter = this.http.build();