Skip to content

Commit 359724e

Browse files
authored
Merge pull request #44144 from michalvavrik/feature/propagate-securit-jpa-exception-root-cause
Propagate Security JPA security exceptions root cause in raised `AuthenticationFailedException`
2 parents 40baf81 + a7a122f commit 359724e

File tree

5 files changed

+53
-5
lines changed

5 files changed

+53
-5
lines changed

extensions/security-jpa-reactive/deployment/src/test/java/io/quarkus/security/jpa/reactive/PanacheEntitiesConfigurationTest.java

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
package io.quarkus.security.jpa.reactive;
22

33
import static org.hamcrest.Matchers.is;
4+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
5+
import static org.junit.jupiter.api.Assertions.assertNotNull;
6+
import static org.junit.jupiter.api.Assertions.assertTrue;
47

8+
import jakarta.enterprise.event.Observes;
9+
import jakarta.inject.Inject;
10+
import jakarta.inject.Singleton;
11+
import jakarta.persistence.NonUniqueResultException;
12+
13+
import org.awaitility.Awaitility;
14+
import org.hamcrest.Matchers;
515
import org.junit.jupiter.api.Test;
616
import org.junit.jupiter.api.extension.RegisterExtension;
717

18+
import io.quarkus.security.AuthenticationFailedException;
19+
import io.quarkus.security.spi.runtime.AuthenticationFailureEvent;
820
import io.quarkus.test.QuarkusUnitTest;
921
import io.restassured.RestAssured;
1022
import io.restassured.response.ValidatableResponse;
@@ -20,9 +32,13 @@ public class PanacheEntitiesConfigurationTest extends JpaSecurityRealmTest {
2032
.addClass(PanacheUserEntity.class)
2133
.addClass(PanacheRoleEntity.class)
2234
.addClass(UserResource.class)
35+
.addClass(AuthenticationFailureObserver.class)
2336
.addAsResource("multiple-entities/import.sql", "import.sql")
2437
.addAsResource("multiple-entities/application.properties", "application.properties"));
2538

39+
@Inject
40+
AuthenticationFailureObserver authenticationFailureObserver;
41+
2642
@Test
2743
void duplicateUsernameTest() {
2844
// duplicate username must lead to 401
@@ -34,8 +50,17 @@ void duplicateUsernameTest() {
3450
// one user
3551
getUsername().statusCode(200).body(is(DUPLICATE_USERNAME));
3652
createUser();
53+
3754
// two users -> NonUniqueResultException -> 401
38-
getUsername().statusCode(401);
55+
authenticationFailureObserver.recordEvents(true);
56+
getUsername().statusCode(401).body(Matchers.emptyOrNullString());
57+
Awaitility.await().untilAsserted(() -> assertNotNull(authenticationFailureObserver.getEvent()));
58+
var authFailureEvent = authenticationFailureObserver.getEvent();
59+
assertInstanceOf(AuthenticationFailedException.class, authFailureEvent.getAuthenticationFailure());
60+
var cause = authFailureEvent.getAuthenticationFailure().getCause();
61+
assertInstanceOf(NonUniqueResultException.class, cause);
62+
assertTrue(cause.getMessage().contains("Query did not return a unique result"));
63+
authenticationFailureObserver.recordEvents(false);
3964
}
4065

4166
private static void createUser() {
@@ -57,4 +82,27 @@ private static ValidatableResponse getUsername() {
5782
.then();
5883
}
5984

85+
@Singleton
86+
public static class AuthenticationFailureObserver {
87+
88+
private volatile boolean record = false;
89+
private volatile AuthenticationFailureEvent event;
90+
91+
void observerAuthFailure(@Observes AuthenticationFailureEvent event) {
92+
if (record) {
93+
this.event = event;
94+
}
95+
}
96+
97+
void recordEvents(boolean record) {
98+
this.record = record;
99+
if (!record) {
100+
this.event = null;
101+
}
102+
}
103+
104+
AuthenticationFailureEvent getEvent() {
105+
return event;
106+
}
107+
}
60108
}

extensions/security-jpa-reactive/runtime/src/main/java/io/quarkus/security/jpa/reactive/runtime/JpaReactiveIdentityProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public boolean test(Throwable throwable) {
4848
@Override
4949
public Throwable apply(Throwable throwable) {
5050
LOG.debug("Authentication failed", throwable);
51-
return new AuthenticationFailedException();
51+
return new AuthenticationFailedException(throwable);
5252
}
5353
});
5454
}

extensions/security-jpa-reactive/runtime/src/main/java/io/quarkus/security/jpa/reactive/runtime/JpaReactiveTrustedIdentityProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public boolean test(Throwable throwable) {
4848
@Override
4949
public Throwable apply(Throwable throwable) {
5050
LOG.debug("Authentication failed", throwable);
51-
return new AuthenticationFailedException();
51+
return new AuthenticationFailedException(throwable);
5252
}
5353
});
5454
}

extensions/security-jpa/runtime/src/main/java/io/quarkus/security/jpa/runtime/JpaIdentityProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ private SecurityIdentity authenticate(UsernamePasswordAuthenticationRequest requ
6060
return authenticate(session, request);
6161
} catch (SecurityException e) {
6262
log.debug("Authentication failed", e);
63-
throw new AuthenticationFailedException();
63+
throw new AuthenticationFailedException(e);
6464
}
6565
}
6666

extensions/security-jpa/runtime/src/main/java/io/quarkus/security/jpa/runtime/JpaTrustedIdentityProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ private SecurityIdentity authenticate(TrustedAuthenticationRequest request) {
6060
return authenticate(session, request);
6161
} catch (SecurityException e) {
6262
log.debug("Authentication failed", e);
63-
throw new AuthenticationFailedException();
63+
throw new AuthenticationFailedException(e);
6464
}
6565
}
6666

0 commit comments

Comments
 (0)