Revert "Support SpEL Returning AuthorizationDecision"
This reverts commit 77f2977c55.
This commit is contained in:
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* 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.access.expression;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.ExpressionAuthorizationDecision;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ExpressionUtilsTests {
|
||||
|
||||
private final Object details = new Object();
|
||||
|
||||
@Test
|
||||
public void evaluateWhenAuthorizationDecisionThenReturns() {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("#root.returnDecision()");
|
||||
StandardEvaluationContext context = new StandardEvaluationContext(this);
|
||||
assertThat(ExpressionUtils.evaluate(expression, context)).isInstanceOf(AuthorizationDecisionDetails.class)
|
||||
.extracting("details")
|
||||
.isEqualTo(this.details);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void evaluateWhenBooleanThenReturnsExpressionAuthorizationDecision() {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("#root.returnResult()");
|
||||
StandardEvaluationContext context = new StandardEvaluationContext(this);
|
||||
assertThat(ExpressionUtils.evaluate(expression, context)).isInstanceOf(ExpressionAuthorizationDecision.class);
|
||||
}
|
||||
|
||||
public AuthorizationDecision returnDecision() {
|
||||
return new AuthorizationDecisionDetails(false, this.details);
|
||||
}
|
||||
|
||||
public boolean returnResult() {
|
||||
return false;
|
||||
}
|
||||
|
||||
static final class AuthorizationDecisionDetails extends AuthorizationDecision {
|
||||
|
||||
final Object details;
|
||||
|
||||
AuthorizationDecisionDetails(boolean granted, Object details) {
|
||||
super(granted);
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,15 +19,16 @@ package org.springframework.security.authorization.method;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
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;
|
||||
@@ -124,10 +125,10 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
MethodInvocation mockMethodInvocation = spy(
|
||||
new MockMethodInvocation(new Sample(), Sample.class.getDeclaredMethod("flux")));
|
||||
given(mockMethodInvocation.proceed()).willReturn(Flux.just("john", "bob"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any())).willAnswer(this::masking);
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.empty());
|
||||
ReactiveAuthorizationManager<MethodInvocationResult> mockReactiveAuthorizationManager = mock(
|
||||
ReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.check(any(), any()))
|
||||
.will((invocation) -> Mono.just(createDecision(new MaskingPostProcessor())));
|
||||
AuthorizationManagerAfterReactiveMethodInterceptor interceptor = new AuthorizationManagerAfterReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
Object result = interceptor.invoke(mockMethodInvocation);
|
||||
@@ -143,16 +144,15 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
MethodInvocation mockMethodInvocation = spy(
|
||||
new MockMethodInvocation(new Sample(), Sample.class.getDeclaredMethod("flux")));
|
||||
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);
|
||||
ReactiveAuthorizationManager<MethodInvocationResult> mockReactiveAuthorizationManager = mock(
|
||||
ReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willAnswer((invocation) -> {
|
||||
MethodInvocationResult argument = invocation.getArgument(1);
|
||||
if ("john".equals(argument.getResult())) {
|
||||
return Mono.just(new AuthorizationDecision(true));
|
||||
}
|
||||
return Mono.just(argument.getResult());
|
||||
return Mono.just(createDecision(new MaskingPostProcessor()));
|
||||
});
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.empty());
|
||||
AuthorizationManagerAfterReactiveMethodInterceptor interceptor = new AuthorizationManagerAfterReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
Object result = interceptor.invoke(mockMethodInvocation);
|
||||
@@ -168,10 +168,11 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
MethodInvocation mockMethodInvocation = spy(
|
||||
new MockMethodInvocation(new Sample(), Sample.class.getDeclaredMethod("mono")));
|
||||
given(mockMethodInvocation.proceed()).willReturn(Mono.just("john"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any())).willAnswer(this::masking);
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.empty());
|
||||
ReactiveAuthorizationManager<MethodInvocationResult> mockReactiveAuthorizationManager = mock(
|
||||
ReactiveAuthorizationManager.class);
|
||||
PostAuthorizeAuthorizationDecision decision = new PostAuthorizeAuthorizationDecision(false,
|
||||
new LiteralExpression("1234"), new MaskingPostProcessor());
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.just(decision));
|
||||
AuthorizationManagerAfterReactiveMethodInterceptor interceptor = new AuthorizationManagerAfterReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
Object result = interceptor.invoke(mockMethodInvocation);
|
||||
@@ -186,10 +187,11 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
MethodInvocation mockMethodInvocation = spy(
|
||||
new MockMethodInvocation(new Sample(), Sample.class.getDeclaredMethod("mono")));
|
||||
given(mockMethodInvocation.proceed()).willReturn(Mono.just("john"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any())).willAnswer(this::monoMasking);
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.empty());
|
||||
ReactiveAuthorizationManager<MethodInvocationResult> mockReactiveAuthorizationManager = mock(
|
||||
ReactiveAuthorizationManager.class);
|
||||
PostAuthorizeAuthorizationDecision decision = new PostAuthorizeAuthorizationDecision(false,
|
||||
new LiteralExpression("1234"), new MonoMaskingPostProcessor());
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.just(decision));
|
||||
AuthorizationManagerAfterReactiveMethodInterceptor interceptor = new AuthorizationManagerAfterReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
Object result = interceptor.invoke(mockMethodInvocation);
|
||||
@@ -204,10 +206,11 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
MethodInvocation mockMethodInvocation = spy(
|
||||
new MockMethodInvocation(new Sample(), Sample.class.getDeclaredMethod("mono")));
|
||||
given(mockMethodInvocation.proceed()).willReturn(Mono.just("john"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.postProcessResult(any(), any())).willReturn(null);
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.empty());
|
||||
ReactiveAuthorizationManager<MethodInvocationResult> mockReactiveAuthorizationManager = mock(
|
||||
ReactiveAuthorizationManager.class);
|
||||
PostAuthorizeAuthorizationDecision decision = new PostAuthorizeAuthorizationDecision(false,
|
||||
new LiteralExpression("1234"), new NullPostProcessor());
|
||||
given(mockReactiveAuthorizationManager.check(any(), any())).willReturn(Mono.just(decision));
|
||||
AuthorizationManagerAfterReactiveMethodInterceptor interceptor = new AuthorizationManagerAfterReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
Object result = interceptor.invoke(mockMethodInvocation);
|
||||
@@ -235,18 +238,34 @@ public class AuthorizationManagerAfterReactiveMethodInterceptorTests {
|
||||
verify(mockReactiveAuthorizationManager).check(any(), any());
|
||||
}
|
||||
|
||||
private Object masking(InvocationOnMock invocation) {
|
||||
MethodInvocationResult result = invocation.getArgument(0);
|
||||
return result.getResult() + "-masked";
|
||||
private PostAuthorizeAuthorizationDecision createDecision(MethodAuthorizationDeniedPostProcessor postProcessor) {
|
||||
return new PostAuthorizeAuthorizationDecision(false, new LiteralExpression("1234"), postProcessor);
|
||||
}
|
||||
|
||||
private Object monoMasking(InvocationOnMock invocation) {
|
||||
MethodInvocationResult result = invocation.getArgument(0);
|
||||
return Mono.just(result.getResult() + "-masked");
|
||||
static class MaskingPostProcessor implements MethodAuthorizationDeniedPostProcessor {
|
||||
|
||||
@Override
|
||||
public Object postProcessResult(MethodInvocationResult contextObject, AuthorizationResult result) {
|
||||
return contextObject.getResult() + "-masked";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface HandlingReactiveAuthorizationManager
|
||||
extends ReactiveAuthorizationManager<MethodInvocationResult>, MethodAuthorizationDeniedPostProcessor {
|
||||
static class MonoMaskingPostProcessor implements MethodAuthorizationDeniedPostProcessor {
|
||||
|
||||
@Override
|
||||
public Object postProcessResult(MethodInvocationResult contextObject, AuthorizationResult result) {
|
||||
return Mono.just(contextObject.getResult() + "-masked");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class NullPostProcessor implements MethodAuthorizationDeniedPostProcessor {
|
||||
|
||||
@Override
|
||||
public Object postProcessResult(MethodInvocationResult contextObject, AuthorizationResult result) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,12 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
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;
|
||||
@@ -123,10 +125,11 @@ public class AuthorizationManagerBeforeReactiveMethodInterceptorTests {
|
||||
MethodInvocation mockMethodInvocation = spy(
|
||||
new MockMethodInvocation(new Sample(), Sample.class.getDeclaredMethod("mono")));
|
||||
given(mockMethodInvocation.proceed()).willReturn(Mono.just("john"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.check(any(), eq(mockMethodInvocation))).willReturn(Mono.empty());
|
||||
given(mockReactiveAuthorizationManager.handle(any(), any())).willReturn("***");
|
||||
ReactiveAuthorizationManager<MethodInvocation> mockReactiveAuthorizationManager = mock(
|
||||
ReactiveAuthorizationManager.class);
|
||||
PreAuthorizeAuthorizationDecision decision = new PreAuthorizeAuthorizationDecision(false,
|
||||
new LiteralExpression("1234"), new MaskingPostProcessor());
|
||||
given(mockReactiveAuthorizationManager.check(any(), eq(mockMethodInvocation))).willReturn(Mono.just(decision));
|
||||
AuthorizationManagerBeforeReactiveMethodInterceptor interceptor = new AuthorizationManagerBeforeReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
Object result = interceptor.invoke(mockMethodInvocation);
|
||||
@@ -141,10 +144,11 @@ public class AuthorizationManagerBeforeReactiveMethodInterceptorTests {
|
||||
MethodInvocation mockMethodInvocation = spy(
|
||||
new MockMethodInvocation(new Sample(), Sample.class.getDeclaredMethod("mono")));
|
||||
given(mockMethodInvocation.proceed()).willReturn(Mono.just("john"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.check(any(), eq(mockMethodInvocation))).willReturn(Mono.empty());
|
||||
given(mockReactiveAuthorizationManager.handle(any(), any())).willReturn(Mono.just("***"));
|
||||
ReactiveAuthorizationManager<MethodInvocation> mockReactiveAuthorizationManager = mock(
|
||||
ReactiveAuthorizationManager.class);
|
||||
PreAuthorizeAuthorizationDecision decision = new PreAuthorizeAuthorizationDecision(false,
|
||||
new LiteralExpression("1234"), new MonoMaskingPostProcessor());
|
||||
given(mockReactiveAuthorizationManager.check(any(), eq(mockMethodInvocation))).willReturn(Mono.just(decision));
|
||||
AuthorizationManagerBeforeReactiveMethodInterceptor interceptor = new AuthorizationManagerBeforeReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
Object result = interceptor.invoke(mockMethodInvocation);
|
||||
@@ -159,10 +163,11 @@ public class AuthorizationManagerBeforeReactiveMethodInterceptorTests {
|
||||
MethodInvocation mockMethodInvocation = spy(
|
||||
new MockMethodInvocation(new Sample(), Sample.class.getDeclaredMethod("flux")));
|
||||
given(mockMethodInvocation.proceed()).willReturn(Flux.just("john", "bob"));
|
||||
HandlingReactiveAuthorizationManager mockReactiveAuthorizationManager = mock(
|
||||
HandlingReactiveAuthorizationManager.class);
|
||||
given(mockReactiveAuthorizationManager.check(any(), eq(mockMethodInvocation))).willReturn(Mono.empty());
|
||||
given(mockReactiveAuthorizationManager.handle(any(), any())).willReturn(Mono.just("***"));
|
||||
ReactiveAuthorizationManager<MethodInvocation> mockReactiveAuthorizationManager = mock(
|
||||
ReactiveAuthorizationManager.class);
|
||||
PreAuthorizeAuthorizationDecision decision = new PreAuthorizeAuthorizationDecision(false,
|
||||
new LiteralExpression("1234"), new MonoMaskingPostProcessor());
|
||||
given(mockReactiveAuthorizationManager.check(any(), eq(mockMethodInvocation))).willReturn(Mono.just(decision));
|
||||
AuthorizationManagerBeforeReactiveMethodInterceptor interceptor = new AuthorizationManagerBeforeReactiveMethodInterceptor(
|
||||
Pointcut.TRUE, mockReactiveAuthorizationManager);
|
||||
Object result = interceptor.invoke(mockMethodInvocation);
|
||||
@@ -209,8 +214,21 @@ public class AuthorizationManagerBeforeReactiveMethodInterceptorTests {
|
||||
verify(mockReactiveAuthorizationManager).check(any(), eq(mockMethodInvocation));
|
||||
}
|
||||
|
||||
interface HandlingReactiveAuthorizationManager
|
||||
extends ReactiveAuthorizationManager<MethodInvocation>, MethodAuthorizationDeniedHandler {
|
||||
static class MaskingPostProcessor implements MethodAuthorizationDeniedHandler {
|
||||
|
||||
@Override
|
||||
public Object handle(MethodInvocation methodInvocation, AuthorizationResult result) {
|
||||
return "***";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class MonoMaskingPostProcessor implements MethodAuthorizationDeniedHandler {
|
||||
|
||||
@Override
|
||||
public Object handle(MethodInvocation methodInvocation, AuthorizationResult result) {
|
||||
return Mono.just("***");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user