1
0
mirror of synced 2026-08-05 17:57:15 +00:00

Add Publishing Predicate

Closes gh-17503
This commit is contained in:
Josh Cummings
2025-07-07 17:54:34 -06:00
parent 901b386ca6
commit c312d18191
3 changed files with 58 additions and 67 deletions
@@ -16,6 +16,7 @@
package org.springframework.security.authorization;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.springframework.context.ApplicationEventPublisher;
@@ -40,6 +41,8 @@ public final class SpringAuthorizationEventPublisher implements AuthorizationEve
private final ApplicationEventPublisher eventPublisher;
private Predicate<AuthorizationResult> shouldPublishResult = (result) -> !result.isGranted();
/**
* Construct this publisher using Spring's {@link ApplicationEventPublisher}
* @param eventPublisher
@@ -55,11 +58,28 @@ public final class SpringAuthorizationEventPublisher implements AuthorizationEve
@Override
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
AuthorizationResult result) {
if (result == null || result.isGranted()) {
if (result == null) {
return;
}
if (!this.shouldPublishResult.test(result)) {
return;
}
AuthorizationDeniedEvent<T> failure = new AuthorizationDeniedEvent<>(authentication, object, result);
this.eventPublisher.publishEvent(failure);
}
/**
* Use this predicate to test whether to publish an event.
*
* <p>
* Since you cannot publish a {@code null} event, checking for null is already
* performed before this test is run
* @param shouldPublishResult the test to perform on non-{@code null} events
* @since 7.0
*/
public void setShouldPublishResult(Predicate<AuthorizationResult> shouldPublishResult) {
Assert.notNull(shouldPublishResult, "shouldPublishResult cannot be null");
this.shouldPublishResult = shouldPublishResult;
}
}
@@ -16,6 +16,7 @@
package org.springframework.security.authorization;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.BeforeEach;
@@ -26,10 +27,13 @@ import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authorization.event.AuthorizationDeniedEvent;
import org.springframework.security.core.Authentication;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Tests for {@link SpringAuthorizationEventPublisher}
@@ -64,4 +68,16 @@ public class SpringAuthorizationEventPublisherTests {
verify(this.applicationEventPublisher).publishEvent(isA(AuthorizationDeniedEvent.class));
}
@Test
public void publishWhenPredicateMatchesThenEvent() {
Predicate<AuthorizationResult> test = mock(Predicate.class);
given(test.test(any())).willReturn(true, false);
this.authorizationEventPublisher.setShouldPublishResult(test);
AuthorizationResult result = new AuthorizationDecision(false);
this.authorizationEventPublisher.publishAuthorizationEvent(this.authentication, mock(Object.class), result);
verify(this.applicationEventPublisher).publishEvent(isA(AuthorizationDeniedEvent.class));
this.authorizationEventPublisher.publishAuthorizationEvent(this.authentication, mock(Object.class), result);
verifyNoMoreInteractions(this.applicationEventPublisher);
}
}