Handle SpEL AuthorizationDeniedExceptions
Closes gh-14600
This commit is contained in:
@@ -26,8 +26,10 @@ import org.springframework.security.authentication.TestAuthentication;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.authorization.AuthenticatedAuthorizationManager;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.AuthorizationDeniedException;
|
||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
@@ -36,6 +38,7 @@ import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||
import org.springframework.security.core.context.SecurityContextImpl;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
@@ -139,4 +142,24 @@ public class AuthorizationManagerAfterMethodInterceptorTests {
|
||||
any(AuthorizationDecision.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeWhenCustomAuthorizationDeniedExceptionThenThrows() throws Throwable {
|
||||
MethodInvocation mi = mock(MethodInvocation.class);
|
||||
given(mi.proceed()).willReturn("ok");
|
||||
AuthorizationManager<MethodInvocationResult> manager = mock(AuthorizationManager.class);
|
||||
given(manager.check(any(), any()))
|
||||
.willThrow(new MyAuthzDeniedException("denied", new AuthorizationDecision(false)));
|
||||
AuthorizationManagerAfterMethodInterceptor advice = new AuthorizationManagerAfterMethodInterceptor(
|
||||
Pointcut.TRUE, manager);
|
||||
assertThatExceptionOfType(MyAuthzDeniedException.class).isThrownBy(() -> advice.invoke(mi));
|
||||
}
|
||||
|
||||
static class MyAuthzDeniedException extends AuthorizationDeniedException {
|
||||
|
||||
MyAuthzDeniedException(String msg, AuthorizationResult authorizationResult) {
|
||||
super(msg, authorizationResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.access.intercept.method.MockMethodInvocation;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.AuthorizationDeniedException;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.authorization.ReactiveAuthorizationManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -126,7 +127,8 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
given(mockMethodInvocation.proceed()).willReturn(Flux.just("john", "bob"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any())).willAnswer(this::masking);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any(AuthorizationResult.class)))
|
||||
.willAnswer(this::masking);
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.empty());
|
||||
AuthorizationManagerAfterReactiveMethodInterceptor interceptor = new AuthorizationManagerAfterReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
@@ -145,13 +147,14 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
given(mockMethodInvocation.proceed()).willReturn(Flux.just("john", "bob"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any())).willAnswer((invocation) -> {
|
||||
MethodInvocationResult argument = invocation.getArgument(0);
|
||||
if (!"john".equals(argument.getResult())) {
|
||||
return monoMasking(invocation);
|
||||
}
|
||||
return Mono.just(argument.getResult());
|
||||
});
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any(AuthorizationResult.class)))
|
||||
.willAnswer((invocation) -> {
|
||||
MethodInvocationResult argument = invocation.getArgument(0);
|
||||
if (!"john".equals(argument.getResult())) {
|
||||
return monoMasking(invocation);
|
||||
}
|
||||
return Mono.just(argument.getResult());
|
||||
});
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.empty());
|
||||
AuthorizationManagerAfterReactiveMethodInterceptor interceptor = new AuthorizationManagerAfterReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
@@ -170,7 +173,8 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
given(mockMethodInvocation.proceed()).willReturn(Mono.just("john"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any())).willAnswer(this::masking);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any(AuthorizationResult.class)))
|
||||
.willAnswer(this::masking);
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.empty());
|
||||
AuthorizationManagerAfterReactiveMethodInterceptor interceptor = new AuthorizationManagerAfterReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
@@ -188,7 +192,8 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
given(mockMethodInvocation.proceed()).willReturn(Mono.just("john"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any())).willAnswer(this::monoMasking);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any(AuthorizationResult.class)))
|
||||
.willAnswer(this::monoMasking);
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.empty());
|
||||
AuthorizationManagerAfterReactiveMethodInterceptor interceptor = new AuthorizationManagerAfterReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
@@ -206,7 +211,8 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
given(mockMethodInvocation.proceed()).willReturn(Mono.just("john"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any())).willReturn(null);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any(AuthorizationResult.class)))
|
||||
.willReturn(null);
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.empty());
|
||||
AuthorizationManagerAfterReactiveMethodInterceptor interceptor = new AuthorizationManagerAfterReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
@@ -235,6 +241,20 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
verify(mockReactiveAuthorizationManager).check(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeWhenCustomAuthorizationDeniedExceptionThenThrows() throws Throwable {
|
||||
MethodInvocation mockMethodInvocation = spy(
|
||||
new MockMethodInvocation(new Sample(), Sample.class.getDeclaredMethod("mono")));
|
||||
given(mockMethodInvocation.proceed()).willReturn(Mono.just("ok"));
|
||||
ReactiveAuthorizationManager<MethodInvocationResult> manager = mock(ReactiveAuthorizationManager.class);
|
||||
given(manager.check(any(), any()))
|
||||
.willReturn(Mono.error(new MyAuthzDeniedException("denied", new AuthorizationDecision(false))));
|
||||
AuthorizationManagerAfterReactiveMethodInterceptor advice = new AuthorizationManagerAfterReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, manager);
|
||||
assertThatExceptionOfType(MyAuthzDeniedException.class)
|
||||
.isThrownBy(() -> ((Mono<?>) advice.invoke(mockMethodInvocation)).block());
|
||||
}
|
||||
|
||||
private Object masking(InvocationOnMock invocation) {
|
||||
MethodInvocationResult result = invocation.getArgument(0);
|
||||
return result.getResult() + "-masked";
|
||||
@@ -262,4 +282,12 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
|
||||
}
|
||||
|
||||
static class MyAuthzDeniedException extends AuthorizationDeniedException {
|
||||
|
||||
MyAuthzDeniedException(String msg, AuthorizationResult authorizationResult) {
|
||||
super(msg, authorizationResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,8 +25,10 @@ import org.springframework.aop.Pointcut;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.authorization.AuthenticatedAuthorizationManager;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.AuthorizationDeniedException;
|
||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
@@ -34,6 +36,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||
import org.springframework.security.core.context.SecurityContextImpl;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@@ -133,4 +136,22 @@ public class AuthorizationManagerBeforeMethodInterceptorTests {
|
||||
any(AuthorizationDecision.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeWhenCustomAuthorizationDeniedExceptionThenThrows() {
|
||||
AuthorizationManager<MethodInvocation> manager = mock(AuthorizationManager.class);
|
||||
given(manager.check(any(), any()))
|
||||
.willThrow(new MyAuthzDeniedException("denied", new AuthorizationDecision(false)));
|
||||
AuthorizationManagerBeforeMethodInterceptor advice = new AuthorizationManagerBeforeMethodInterceptor(
|
||||
Pointcut.TRUE, manager);
|
||||
assertThatExceptionOfType(MyAuthzDeniedException.class).isThrownBy(() -> advice.invoke(null));
|
||||
}
|
||||
|
||||
static class MyAuthzDeniedException extends AuthorizationDeniedException {
|
||||
|
||||
MyAuthzDeniedException(String msg, AuthorizationResult authorizationResult) {
|
||||
super(msg, authorizationResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.access.intercept.method.MockMethodInvocation;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.AuthorizationDeniedException;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.authorization.ReactiveAuthorizationManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -126,7 +127,7 @@ public class AuthorizationManagerBeforeReactiveMethodInterceptorTests {
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.check(any(), eq(mockMethodInvocation))).willReturn(Mono.empty());
|
||||
given(mockReactiveAuthorizationManager.handle(any(), any())).willReturn("***");
|
||||
given(mockReactiveAuthorizationManager.handle(any(), any(AuthorizationResult.class))).willReturn("***");
|
||||
AuthorizationManagerBeforeReactiveMethodInterceptor interceptor = new AuthorizationManagerBeforeReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
Object result = interceptor.invoke(mockMethodInvocation);
|
||||
@@ -144,7 +145,8 @@ public class AuthorizationManagerBeforeReactiveMethodInterceptorTests {
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.check(any(), eq(mockMethodInvocation))).willReturn(Mono.empty());
|
||||
given(mockReactiveAuthorizationManager.handle(any(), any())).willReturn(Mono.just("***"));
|
||||
given(mockReactiveAuthorizationManager.handle(any(), any(AuthorizationResult.class)))
|
||||
.willReturn(Mono.just("***"));
|
||||
AuthorizationManagerBeforeReactiveMethodInterceptor interceptor = new AuthorizationManagerBeforeReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
Object result = interceptor.invoke(mockMethodInvocation);
|
||||
@@ -162,7 +164,8 @@ public class AuthorizationManagerBeforeReactiveMethodInterceptorTests {
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.check(any(), eq(mockMethodInvocation))).willReturn(Mono.empty());
|
||||
given(mockReactiveAuthorizationManager.handle(any(), any())).willReturn(Mono.just("***"));
|
||||
given(mockReactiveAuthorizationManager.handle(any(), any(AuthorizationResult.class)))
|
||||
.willReturn(Mono.just("***"));
|
||||
AuthorizationManagerBeforeReactiveMethodInterceptor interceptor = new AuthorizationManagerBeforeReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
Object result = interceptor.invoke(mockMethodInvocation);
|
||||
@@ -209,6 +212,19 @@ public class AuthorizationManagerBeforeReactiveMethodInterceptorTests {
|
||||
verify(mockReactiveAuthorizationManager).check(any(), eq(mockMethodInvocation));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeWhenCustomAuthorizationDeniedExceptionThenThrows() throws Throwable {
|
||||
MethodInvocation mockMethodInvocation = spy(
|
||||
new MockMethodInvocation(new Sample(), Sample.class.getDeclaredMethod("flux")));
|
||||
ReactiveAuthorizationManager<MethodInvocation> manager = mock(ReactiveAuthorizationManager.class);
|
||||
given(manager.check(any(), any()))
|
||||
.willThrow(new MyAuthzDeniedException("denied", new AuthorizationDecision(false)));
|
||||
AuthorizationManagerBeforeReactiveMethodInterceptor advice = new AuthorizationManagerBeforeReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, manager);
|
||||
assertThatExceptionOfType(MyAuthzDeniedException.class)
|
||||
.isThrownBy(() -> ((Mono<?>) advice.invoke(mockMethodInvocation)).block());
|
||||
}
|
||||
|
||||
interface HandlingReactiveAuthorizationManager
|
||||
extends ReactiveAuthorizationManager<MethodInvocation>, MethodAuthorizationDeniedHandler {
|
||||
|
||||
@@ -226,4 +242,12 @@ public class AuthorizationManagerBeforeReactiveMethodInterceptorTests {
|
||||
|
||||
}
|
||||
|
||||
static class MyAuthzDeniedException extends AuthorizationDeniedException {
|
||||
|
||||
MyAuthzDeniedException(String msg, AuthorizationResult authorizationResult) {
|
||||
super(msg, authorizationResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user