Skip to content

Commit

Permalink
Merge pull request #44144 from michalvavrik/feature/propagate-securit…
Browse files Browse the repository at this point in the history
…-jpa-exception-root-cause

Propagate Security JPA security exceptions root cause in raised `AuthenticationFailedException`
  • Loading branch information
sberyozkin authored Oct 29, 2024
2 parents 40baf81 + a7a122f commit 359724e
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
package io.quarkus.security.jpa.reactive;

import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.persistence.NonUniqueResultException;

import org.awaitility.Awaitility;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.spi.runtime.AuthenticationFailureEvent;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
import io.restassured.response.ValidatableResponse;
Expand All @@ -20,9 +32,13 @@ public class PanacheEntitiesConfigurationTest extends JpaSecurityRealmTest {
.addClass(PanacheUserEntity.class)
.addClass(PanacheRoleEntity.class)
.addClass(UserResource.class)
.addClass(AuthenticationFailureObserver.class)
.addAsResource("multiple-entities/import.sql", "import.sql")
.addAsResource("multiple-entities/application.properties", "application.properties"));

@Inject
AuthenticationFailureObserver authenticationFailureObserver;

@Test
void duplicateUsernameTest() {
// duplicate username must lead to 401
Expand All @@ -34,8 +50,17 @@ void duplicateUsernameTest() {
// one user
getUsername().statusCode(200).body(is(DUPLICATE_USERNAME));
createUser();

// two users -> NonUniqueResultException -> 401
getUsername().statusCode(401);
authenticationFailureObserver.recordEvents(true);
getUsername().statusCode(401).body(Matchers.emptyOrNullString());
Awaitility.await().untilAsserted(() -> assertNotNull(authenticationFailureObserver.getEvent()));
var authFailureEvent = authenticationFailureObserver.getEvent();
assertInstanceOf(AuthenticationFailedException.class, authFailureEvent.getAuthenticationFailure());
var cause = authFailureEvent.getAuthenticationFailure().getCause();
assertInstanceOf(NonUniqueResultException.class, cause);
assertTrue(cause.getMessage().contains("Query did not return a unique result"));
authenticationFailureObserver.recordEvents(false);
}

private static void createUser() {
Expand All @@ -57,4 +82,27 @@ private static ValidatableResponse getUsername() {
.then();
}

@Singleton
public static class AuthenticationFailureObserver {

private volatile boolean record = false;
private volatile AuthenticationFailureEvent event;

void observerAuthFailure(@Observes AuthenticationFailureEvent event) {
if (record) {
this.event = event;
}
}

void recordEvents(boolean record) {
this.record = record;
if (!record) {
this.event = null;
}
}

AuthenticationFailureEvent getEvent() {
return event;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public boolean test(Throwable throwable) {
@Override
public Throwable apply(Throwable throwable) {
LOG.debug("Authentication failed", throwable);
return new AuthenticationFailedException();
return new AuthenticationFailedException(throwable);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public boolean test(Throwable throwable) {
@Override
public Throwable apply(Throwable throwable) {
LOG.debug("Authentication failed", throwable);
return new AuthenticationFailedException();
return new AuthenticationFailedException(throwable);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ private SecurityIdentity authenticate(UsernamePasswordAuthenticationRequest requ
return authenticate(session, request);
} catch (SecurityException e) {
log.debug("Authentication failed", e);
throw new AuthenticationFailedException();
throw new AuthenticationFailedException(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ private SecurityIdentity authenticate(TrustedAuthenticationRequest request) {
return authenticate(session, request);
} catch (SecurityException e) {
log.debug("Authentication failed", e);
throw new AuthenticationFailedException();
throw new AuthenticationFailedException(e);
}
}

Expand Down

0 comments on commit 359724e

Please sign in to comment.