AuthorizationEventPublisher Accepts AuthorizationResult
Closes gh-15915 Co-authored-by: Max Batischev <mblancer@mail.ru>
This commit is contained in:
parent
ef1226ddf8
commit
702538ebce
|
@ -75,6 +75,7 @@ import org.springframework.security.access.prepost.PreFilter;
|
||||||
import org.springframework.security.authorization.AuthorizationDecision;
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
|
import org.springframework.security.authorization.AuthorizationResult;
|
||||||
import org.springframework.security.authorization.method.AuthorizationAdvisor;
|
import org.springframework.security.authorization.method.AuthorizationAdvisor;
|
||||||
import org.springframework.security.authorization.method.AuthorizationAdvisorProxyFactory;
|
import org.springframework.security.authorization.method.AuthorizationAdvisorProxyFactory;
|
||||||
import org.springframework.security.authorization.method.AuthorizationAdvisorProxyFactory.TargetVisitor;
|
import org.springframework.security.authorization.method.AuthorizationAdvisorProxyFactory.TargetVisitor;
|
||||||
|
@ -110,6 +111,7 @@ import static org.assertj.core.api.Assertions.assertThatNoException;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
import static org.mockito.Mockito.clearInvocations;
|
import static org.mockito.Mockito.clearInvocations;
|
||||||
|
import static org.mockito.Mockito.doCallRealMethod;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
|
@ -1293,6 +1295,8 @@ public class PrePostMethodSecurityConfigurationTests {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
AuthorizationEventPublisher authorizationEventPublisher() {
|
AuthorizationEventPublisher authorizationEventPublisher() {
|
||||||
|
doCallRealMethod().when(this.publisher)
|
||||||
|
.publishAuthorizationEvent(any(), any(), any(AuthorizationResult.class));
|
||||||
return this.publisher;
|
return this.publisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -42,6 +42,7 @@ import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
import org.springframework.security.authorization.AuthorizationObservationContext;
|
import org.springframework.security.authorization.AuthorizationObservationContext;
|
||||||
|
import org.springframework.security.authorization.AuthorizationResult;
|
||||||
import org.springframework.security.config.ObjectPostProcessor;
|
import org.springframework.security.config.ObjectPostProcessor;
|
||||||
import org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry;
|
import org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
@ -78,6 +79,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
|
import static org.mockito.Mockito.doCallRealMethod;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
@ -1241,6 +1243,8 @@ public class AuthorizeHttpRequestsConfigurerTests {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
AuthorizationEventPublisher authorizationEventPublisher() {
|
AuthorizationEventPublisher authorizationEventPublisher() {
|
||||||
|
doCallRealMethod().when(this.publisher)
|
||||||
|
.publishAuthorizationEvent(any(), any(), any(AuthorizationResult.class));
|
||||||
return this.publisher;
|
return this.publisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -42,8 +42,37 @@ public interface AuthorizationEventPublisher {
|
||||||
* @param object the secured object
|
* @param object the secured object
|
||||||
* @param decision the decision about whether the user may access the secured object
|
* @param decision the decision about whether the user may access the secured object
|
||||||
* @param <T> the secured object's type
|
* @param <T> the secured object's type
|
||||||
|
* @deprecated use
|
||||||
|
* {@link #publishAuthorizationEvent(Supplier, Object, AuthorizationResult)} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
<T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
<T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||||
AuthorizationDecision decision);
|
AuthorizationDecision decision);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publish the given details in the form of an event, typically
|
||||||
|
* {@link AuthorizationGrantedEvent} or {@link AuthorizationDeniedEvent}.
|
||||||
|
*
|
||||||
|
* Note that success events can be very noisy if enabled by default. Because of this
|
||||||
|
* implementations may choose to drop success events by default.
|
||||||
|
* @param authentication a {@link Supplier} for the current user
|
||||||
|
* @param object the secured object
|
||||||
|
* @param result {@link AuthorizationResult} the result about whether the user may
|
||||||
|
* access the secured object
|
||||||
|
* @param <T> the secured object's type
|
||||||
|
* @since 6.4
|
||||||
|
*/
|
||||||
|
default <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||||
|
AuthorizationResult result) {
|
||||||
|
if (result == null) {
|
||||||
|
publishAuthorizationEvent(authentication, object, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (result instanceof AuthorizationDecision decision) {
|
||||||
|
publishAuthorizationEvent(authentication, object, decision);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new UnsupportedOperationException("result must be of type AuthorizationDecision");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,10 +55,16 @@ public final class SpringAuthorizationEventPublisher implements AuthorizationEve
|
||||||
@Override
|
@Override
|
||||||
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||||
AuthorizationDecision decision) {
|
AuthorizationDecision decision) {
|
||||||
if (decision == null || decision.isGranted()) {
|
publishAuthorizationEvent(authentication, object, (AuthorizationResult) decision);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||||
|
AuthorizationResult result) {
|
||||||
|
if (result == null || result.isGranted()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AuthorizationDeniedEvent<T> failure = new AuthorizationDeniedEvent<>(authentication, object, decision);
|
AuthorizationDeniedEvent<T> failure = new AuthorizationDeniedEvent<>(authentication, object, result);
|
||||||
this.eventPublisher.publishEvent(failure);
|
this.eventPublisher.publishEvent(failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
import org.springframework.security.authorization.AuthorizationDecision;
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
|
import org.springframework.security.authorization.AuthorizationResult;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,10 +32,21 @@ import org.springframework.security.core.Authentication;
|
||||||
*/
|
*/
|
||||||
public class AuthorizationDeniedEvent<T> extends AuthorizationEvent {
|
public class AuthorizationDeniedEvent<T> extends AuthorizationEvent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Please use an {@link AuthorizationResult} constructor instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public AuthorizationDeniedEvent(Supplier<Authentication> authentication, T object, AuthorizationDecision decision) {
|
public AuthorizationDeniedEvent(Supplier<Authentication> authentication, T object, AuthorizationDecision decision) {
|
||||||
super(authentication, object, decision);
|
super(authentication, object, decision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 6.4
|
||||||
|
*/
|
||||||
|
public AuthorizationDeniedEvent(Supplier<Authentication> authentication, T object, AuthorizationResult result) {
|
||||||
|
super(authentication, object, result);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the object to which access was requested
|
* Get the object to which access was requested
|
||||||
* @return the object to which access was requested
|
* @return the object to which access was requested
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
import org.springframework.security.authorization.AuthorizationDecision;
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
|
import org.springframework.security.authorization.AuthorizationResult;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
@ -34,19 +35,32 @@ public class AuthorizationEvent extends ApplicationEvent {
|
||||||
|
|
||||||
private final Supplier<Authentication> authentication;
|
private final Supplier<Authentication> authentication;
|
||||||
|
|
||||||
private final AuthorizationDecision decision;
|
private final AuthorizationResult result;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an {@link AuthorizationEvent}
|
* Construct an {@link AuthorizationEvent}
|
||||||
* @param authentication the principal requiring access
|
* @param authentication the principal requiring access
|
||||||
* @param object the object to which access was requested
|
* @param object the object to which access was requested
|
||||||
* @param decision whether authorization was granted or denied
|
* @param result whether authorization was granted or denied
|
||||||
*/
|
*/
|
||||||
public AuthorizationEvent(Supplier<Authentication> authentication, Object object, AuthorizationDecision decision) {
|
public AuthorizationEvent(Supplier<Authentication> authentication, Object object, AuthorizationDecision result) {
|
||||||
super(object);
|
super(object);
|
||||||
Assert.notNull(authentication, "authentication supplier cannot be null");
|
Assert.notNull(authentication, "authentication supplier cannot be null");
|
||||||
this.authentication = authentication;
|
this.authentication = authentication;
|
||||||
this.decision = decision;
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an {@link AuthorizationEvent}
|
||||||
|
* @param authentication the principal requiring access
|
||||||
|
* @param object the object to which access was requested
|
||||||
|
* @param result whether authorization was granted or denied
|
||||||
|
*/
|
||||||
|
public AuthorizationEvent(Supplier<Authentication> authentication, Object object, AuthorizationResult result) {
|
||||||
|
super(object);
|
||||||
|
Assert.notNull(authentication, "authentication supplier cannot be null");
|
||||||
|
this.authentication = authentication;
|
||||||
|
this.result = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,9 +82,27 @@ public class AuthorizationEvent extends ApplicationEvent {
|
||||||
/**
|
/**
|
||||||
* Get the response to the principal's request
|
* Get the response to the principal's request
|
||||||
* @return the response to the principal's request
|
* @return the response to the principal's request
|
||||||
|
* @deprecated please use {@link #getAuthorizationResult()}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public AuthorizationDecision getAuthorizationDecision() {
|
public AuthorizationDecision getAuthorizationDecision() {
|
||||||
return this.decision;
|
if (this.result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (this.result instanceof AuthorizationDecision decision) {
|
||||||
|
return decision;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Please either call getAuthorizationResult or ensure that the result is of type AuthorizationDecision");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the response to the principal's request
|
||||||
|
* @return the response to the principal's request
|
||||||
|
* @since 6.4
|
||||||
|
*/
|
||||||
|
public AuthorizationResult getAuthorizationResult() {
|
||||||
|
return this.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
import org.springframework.security.authorization.AuthorizationDecision;
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
|
import org.springframework.security.authorization.AuthorizationResult;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,11 +32,23 @@ import org.springframework.security.core.Authentication;
|
||||||
*/
|
*/
|
||||||
public class AuthorizationGrantedEvent<T> extends AuthorizationEvent {
|
public class AuthorizationGrantedEvent<T> extends AuthorizationEvent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated please use a constructor that takes an
|
||||||
|
* {@link org.springframework.security.authorization.AuthorizationResult}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public AuthorizationGrantedEvent(Supplier<Authentication> authentication, T object,
|
public AuthorizationGrantedEvent(Supplier<Authentication> authentication, T object,
|
||||||
AuthorizationDecision decision) {
|
AuthorizationDecision decision) {
|
||||||
super(authentication, object, decision);
|
super(authentication, object, decision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 6.4
|
||||||
|
*/
|
||||||
|
public AuthorizationGrantedEvent(Supplier<Authentication> authentication, T object, AuthorizationResult result) {
|
||||||
|
super(authentication, object, result);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the object to which access was requested
|
* Get the object to which access was requested
|
||||||
* @return the object to which access was requested
|
* @return the object to which access was requested
|
||||||
|
|
|
@ -60,7 +60,7 @@ public final class AuthorizationManagerAfterMethodInterceptor implements Authori
|
||||||
|
|
||||||
private int order;
|
private int order;
|
||||||
|
|
||||||
private AuthorizationEventPublisher eventPublisher = AuthorizationManagerAfterMethodInterceptor::noPublish;
|
private AuthorizationEventPublisher eventPublisher = new NoOpAuthorizationEventPublisher();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance.
|
* Creates an instance.
|
||||||
|
@ -209,9 +209,4 @@ public final class AuthorizationManagerAfterMethodInterceptor implements Authori
|
||||||
return authentication;
|
return authentication;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> void noPublish(Supplier<Authentication> authentication, T object,
|
|
||||||
AuthorizationDecision decision) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ public final class AuthorizationManagerBeforeMethodInterceptor implements Author
|
||||||
|
|
||||||
private int order = AuthorizationInterceptorsOrder.FIRST.getOrder();
|
private int order = AuthorizationInterceptorsOrder.FIRST.getOrder();
|
||||||
|
|
||||||
private AuthorizationEventPublisher eventPublisher = AuthorizationManagerBeforeMethodInterceptor::noPublish;
|
private AuthorizationEventPublisher eventPublisher = new NoOpAuthorizationEventPublisher();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance.
|
* Creates an instance.
|
||||||
|
@ -299,9 +299,4 @@ public final class AuthorizationManagerBeforeMethodInterceptor implements Author
|
||||||
return authentication;
|
return authentication;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> void noPublish(Supplier<Authentication> authentication, T object,
|
|
||||||
AuthorizationDecision decision) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2024 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.security.authorization.method;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
|
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||||
|
import org.springframework.security.authorization.AuthorizationResult;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link AuthorizationEventPublisher} implementation that does nothing.
|
||||||
|
*
|
||||||
|
* @author Max Batischev
|
||||||
|
* @since 6.4
|
||||||
|
*/
|
||||||
|
final class NoOpAuthorizationEventPublisher implements AuthorizationEventPublisher {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||||
|
AuthorizationDecision decision) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||||
|
AuthorizationResult result) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -42,6 +42,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Mockito.doCallRealMethod;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
@ -127,6 +128,8 @@ public class AuthorizationManagerAfterMethodInterceptorTests {
|
||||||
AuthorizationManagerAfterMethodInterceptor advice = new AuthorizationManagerAfterMethodInterceptor(
|
AuthorizationManagerAfterMethodInterceptor advice = new AuthorizationManagerAfterMethodInterceptor(
|
||||||
Pointcut.TRUE, AuthenticatedAuthorizationManager.authenticated());
|
Pointcut.TRUE, AuthenticatedAuthorizationManager.authenticated());
|
||||||
AuthorizationEventPublisher eventPublisher = mock(AuthorizationEventPublisher.class);
|
AuthorizationEventPublisher eventPublisher = mock(AuthorizationEventPublisher.class);
|
||||||
|
doCallRealMethod().when(eventPublisher)
|
||||||
|
.publishAuthorizationEvent(any(Supplier.class), any(), any(AuthorizationResult.class));
|
||||||
advice.setAuthorizationEventPublisher(eventPublisher);
|
advice.setAuthorizationEventPublisher(eventPublisher);
|
||||||
|
|
||||||
SecurityContext securityContext = new SecurityContextImpl();
|
SecurityContext securityContext = new SecurityContextImpl();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -41,6 +41,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Mockito.doCallRealMethod;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
@ -121,6 +122,7 @@ public class AuthorizationManagerBeforeMethodInterceptorTests {
|
||||||
AuthorizationManagerBeforeMethodInterceptor advice = new AuthorizationManagerBeforeMethodInterceptor(
|
AuthorizationManagerBeforeMethodInterceptor advice = new AuthorizationManagerBeforeMethodInterceptor(
|
||||||
Pointcut.TRUE, AuthenticatedAuthorizationManager.authenticated());
|
Pointcut.TRUE, AuthenticatedAuthorizationManager.authenticated());
|
||||||
AuthorizationEventPublisher eventPublisher = mock(AuthorizationEventPublisher.class);
|
AuthorizationEventPublisher eventPublisher = mock(AuthorizationEventPublisher.class);
|
||||||
|
doCallRealMethod().when(eventPublisher).publishAuthorizationEvent(any(), any(), any(AuthorizationResult.class));
|
||||||
advice.setAuthorizationEventPublisher(eventPublisher);
|
advice.setAuthorizationEventPublisher(eventPublisher);
|
||||||
|
|
||||||
SecurityContext securityContext = new SecurityContextImpl();
|
SecurityContext securityContext = new SecurityContextImpl();
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
springBootVersion=3.3.3
|
springBootVersion=3.3.3
|
||||||
version=6.4.0-SNAPSHOT
|
version=6.4.0-SNAPSHOT
|
||||||
samplesBranch=main
|
samplesBranch=main
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.springframework.security.authentication.AuthenticationCredentialsNotF
|
||||||
import org.springframework.security.authorization.AuthorizationDecision;
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
|
import org.springframework.security.authorization.AuthorizationResult;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||||
|
@ -114,6 +115,11 @@ public final class AuthorizationChannelInterceptor implements ChannelInterceptor
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||||
|
AuthorizationResult result) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -30,6 +30,7 @@ import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
import org.springframework.security.authorization.AuthorizationDecision;
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
|
import org.springframework.security.authorization.AuthorizationResult;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Mockito.lenient;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,6 +104,9 @@ public class AuthorizationChannelInterceptorTests {
|
||||||
public void preSendWhenAuthorizationEventPublisherThenPublishes() {
|
public void preSendWhenAuthorizationEventPublisherThenPublishes() {
|
||||||
this.interceptor.setAuthorizationEventPublisher(this.eventPublisher);
|
this.interceptor.setAuthorizationEventPublisher(this.eventPublisher);
|
||||||
given(this.authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(true));
|
given(this.authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(true));
|
||||||
|
lenient().doCallRealMethod()
|
||||||
|
.when(this.eventPublisher)
|
||||||
|
.publishAuthorizationEvent(any(), any(), any(AuthorizationResult.class));
|
||||||
this.interceptor.preSend(this.message, this.channel);
|
this.interceptor.preSend(this.message, this.channel);
|
||||||
verify(this.eventPublisher).publishAuthorizationEvent(any(), any(), any());
|
verify(this.eventPublisher).publishAuthorizationEvent(any(), any(), any());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -33,6 +33,7 @@ import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
import org.springframework.security.authorization.AuthorizationDeniedException;
|
import org.springframework.security.authorization.AuthorizationDeniedException;
|
||||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
|
import org.springframework.security.authorization.AuthorizationResult;
|
||||||
import org.springframework.security.authorization.event.AuthorizationDeniedEvent;
|
import org.springframework.security.authorization.event.AuthorizationDeniedEvent;
|
||||||
import org.springframework.security.authorization.event.AuthorizationGrantedEvent;
|
import org.springframework.security.authorization.event.AuthorizationGrantedEvent;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
@ -55,7 +56,7 @@ public class AuthorizationFilter extends GenericFilterBean {
|
||||||
|
|
||||||
private final AuthorizationManager<HttpServletRequest> authorizationManager;
|
private final AuthorizationManager<HttpServletRequest> authorizationManager;
|
||||||
|
|
||||||
private AuthorizationEventPublisher eventPublisher = AuthorizationFilter::noPublish;
|
private AuthorizationEventPublisher eventPublisher = new NoopAuthorizationEventPublisher();
|
||||||
|
|
||||||
private boolean observeOncePerRequest = false;
|
private boolean observeOncePerRequest = false;
|
||||||
|
|
||||||
|
@ -195,11 +196,6 @@ public class AuthorizationFilter extends GenericFilterBean {
|
||||||
this.filterAsyncDispatch = shouldFilterAllDispatcherTypes;
|
this.filterAsyncDispatch = shouldFilterAllDispatcherTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> void noPublish(Supplier<Authentication> authentication, T object,
|
|
||||||
AuthorizationDecision decision) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isObserveOncePerRequest() {
|
public boolean isObserveOncePerRequest() {
|
||||||
return this.observeOncePerRequest;
|
return this.observeOncePerRequest;
|
||||||
}
|
}
|
||||||
|
@ -235,4 +231,19 @@ public class AuthorizationFilter extends GenericFilterBean {
|
||||||
this.filterAsyncDispatch = filterAsyncDispatch;
|
this.filterAsyncDispatch = filterAsyncDispatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class NoopAuthorizationEventPublisher implements AuthorizationEventPublisher {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||||
|
AuthorizationDecision decision) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
|
||||||
|
AuthorizationResult result) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -38,6 +38,7 @@ import org.springframework.security.authorization.AuthenticatedAuthorizationMana
|
||||||
import org.springframework.security.authorization.AuthorizationDecision;
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
|
import org.springframework.security.authorization.AuthorizationResult;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
@ -53,6 +54,7 @@ import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
import static org.mockito.BDDMockito.willThrow;
|
import static org.mockito.BDDMockito.willThrow;
|
||||||
|
import static org.mockito.Mockito.doCallRealMethod;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
@ -186,6 +188,7 @@ public class AuthorizationFilterTests {
|
||||||
SecurityContextHolder.setContext(securityContext);
|
SecurityContextHolder.setContext(securityContext);
|
||||||
|
|
||||||
AuthorizationEventPublisher eventPublisher = mock(AuthorizationEventPublisher.class);
|
AuthorizationEventPublisher eventPublisher = mock(AuthorizationEventPublisher.class);
|
||||||
|
doCallRealMethod().when(eventPublisher).publishAuthorizationEvent(any(), any(), any(AuthorizationResult.class));
|
||||||
authorizationFilter.setAuthorizationEventPublisher(eventPublisher);
|
authorizationFilter.setAuthorizationEventPublisher(eventPublisher);
|
||||||
authorizationFilter.doFilter(mockRequest, mockResponse, mockFilterChain);
|
authorizationFilter.doFilter(mockRequest, mockResponse, mockFilterChain);
|
||||||
verify(eventPublisher).publishAuthorizationEvent(any(Supplier.class), any(HttpServletRequest.class),
|
verify(eventPublisher).publishAuthorizationEvent(any(Supplier.class), any(HttpServletRequest.class),
|
||||||
|
|
Loading…
Reference in New Issue