Provide Authentication to AuthenticationExceptions
Issue gh-16444
This commit is contained in:
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -26,6 +26,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -58,6 +59,7 @@ public class DelegatingReactiveAuthenticationManager implements ReactiveAuthenti
|
||||
public Mono<Authentication> authenticate(Authentication authentication) {
|
||||
Flux<ReactiveAuthenticationManager> result = Flux.fromIterable(this.delegates);
|
||||
Function<ReactiveAuthenticationManager, Mono<Authentication>> logging = (m) -> m.authenticate(authentication)
|
||||
.doOnError(AuthenticationException.class, (ex) -> ex.setAuthenticationRequest(authentication))
|
||||
.doOnError(this.logger::debug);
|
||||
|
||||
return ((this.continueOnError) ? result.concatMapDelayError(logging) : result.concatMap(logging)).next();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -202,6 +202,7 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
|
||||
throw ex;
|
||||
}
|
||||
catch (AuthenticationException ex) {
|
||||
ex.setAuthenticationRequest(authentication);
|
||||
logger.debug(LogMessage.format("Authentication failed with provider %s since %s",
|
||||
provider.getClass().getSimpleName(), ex.getMessage()));
|
||||
lastException = ex;
|
||||
@@ -265,6 +266,7 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void prepareException(AuthenticationException ex, Authentication auth) {
|
||||
ex.setAuthenticationRequest(auth);
|
||||
this.eventPublisher.publishAuthenticationFailure(ex, auth);
|
||||
}
|
||||
|
||||
|
||||
+11
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 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.
|
||||
@@ -26,6 +26,7 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -108,6 +109,15 @@ public class DelegatingReactiveAuthenticationManagerTests {
|
||||
assertThat(manager.authenticate(this.authentication).block()).isEqualTo(this.authentication);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenAccountStatusExceptionThenAuthenticationRequestIsIncluded() {
|
||||
AuthenticationException expected = new LockedException("");
|
||||
given(this.delegate1.authenticate(any())).willReturn(Mono.error(expected));
|
||||
ReactiveAuthenticationManager manager = new DelegatingReactiveAuthenticationManager(this.delegate1);
|
||||
StepVerifier.create(manager.authenticate(this.authentication)).expectError(LockedException.class).verify();
|
||||
assertThat(expected.getAuthenticationRequest()).isEqualTo(this.authentication);
|
||||
}
|
||||
|
||||
private DelegatingReactiveAuthenticationManager managerWithContinueOnError() {
|
||||
DelegatingReactiveAuthenticationManager manager = new DelegatingReactiveAuthenticationManager(this.delegate1,
|
||||
this.delegate2);
|
||||
|
||||
+28
@@ -253,6 +253,34 @@ public class ProviderManagerTests {
|
||||
verify(publisher).publishAuthenticationFailure(expected, authReq);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenAccountStatusExceptionThenAuthenticationRequestIsIncluded() {
|
||||
AuthenticationException expected = new LockedException("");
|
||||
ProviderManager mgr = new ProviderManager(createProviderWhichThrows(expected));
|
||||
Authentication authReq = mock(Authentication.class);
|
||||
assertThatExceptionOfType(LockedException.class).isThrownBy(() -> mgr.authenticate(authReq));
|
||||
assertThat(expected.getAuthenticationRequest()).isEqualTo(authReq);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenInternalServiceAuthenticationExceptionThenAuthenticationRequestIsIncluded() {
|
||||
AuthenticationException expected = new InternalAuthenticationServiceException("");
|
||||
ProviderManager mgr = new ProviderManager(createProviderWhichThrows(expected));
|
||||
Authentication authReq = mock(Authentication.class);
|
||||
assertThatExceptionOfType(InternalAuthenticationServiceException.class)
|
||||
.isThrownBy(() -> mgr.authenticate(authReq));
|
||||
assertThat(expected.getAuthenticationRequest()).isEqualTo(authReq);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenAuthenticationExceptionThenAuthenticationRequestIsIncluded() {
|
||||
AuthenticationException expected = new BadCredentialsException("");
|
||||
ProviderManager mgr = new ProviderManager(createProviderWhichThrows(expected));
|
||||
Authentication authReq = mock(Authentication.class);
|
||||
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> mgr.authenticate(authReq));
|
||||
assertThat(expected.getAuthenticationRequest()).isEqualTo(authReq);
|
||||
}
|
||||
|
||||
// SEC-2367
|
||||
@Test
|
||||
void providerThrowsInternalAuthenticationServiceException() {
|
||||
|
||||
Reference in New Issue
Block a user