Revert "Support SpEL Returning AuthorizationDecision"
This reverts commit 77f2977c55.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -19,43 +19,12 @@ package org.springframework.security.access.expression;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.authorization.ExpressionAuthorizationDecision;
|
||||
|
||||
public final class ExpressionUtils {
|
||||
|
||||
private ExpressionUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate a SpEL expression and coerce into an {@link AuthorizationDecision}
|
||||
* @param expr a SpEL expression
|
||||
* @param ctx an {@link EvaluationContext}
|
||||
* @return the resulting {@link AuthorizationDecision}
|
||||
* @since 6.3
|
||||
*/
|
||||
public static AuthorizationResult evaluate(Expression expr, EvaluationContext ctx) {
|
||||
try {
|
||||
Object result = expr.getValue(ctx);
|
||||
if (result instanceof AuthorizationResult decision) {
|
||||
return decision;
|
||||
}
|
||||
if (result instanceof Boolean granted) {
|
||||
return new ExpressionAuthorizationDecision(granted, expr);
|
||||
}
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"SpEL expression must return either a Boolean or an AuthorizationDecision");
|
||||
}
|
||||
catch (EvaluationException ex) {
|
||||
throw new IllegalArgumentException("Failed to evaluate expression '" + expr.getExpressionString() + "'",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean evaluateAsBoolean(Expression expr, EvaluationContext ctx) {
|
||||
try {
|
||||
return expr.getValue(ctx, Boolean.class);
|
||||
|
||||
@@ -21,17 +21,11 @@ import java.util.function.Supplier;
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationConvention;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.MessageSourceAware;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authorization.method.MethodAuthorizationDeniedHandler;
|
||||
import org.springframework.security.authorization.method.MethodAuthorizationDeniedPostProcessor;
|
||||
import org.springframework.security.authorization.method.MethodInvocationResult;
|
||||
import org.springframework.security.authorization.method.ThrowingMethodAuthorizationDeniedHandler;
|
||||
import org.springframework.security.authorization.method.ThrowingMethodAuthorizationDeniedPostProcessor;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.SpringSecurityMessageSource;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -42,8 +36,7 @@ import org.springframework.util.Assert;
|
||||
* @author Josh Cummings
|
||||
* @since 6.0
|
||||
*/
|
||||
public final class ObservationAuthorizationManager<T> implements AuthorizationManager<T>, MessageSourceAware,
|
||||
MethodAuthorizationDeniedHandler, MethodAuthorizationDeniedPostProcessor {
|
||||
public final class ObservationAuthorizationManager<T> implements AuthorizationManager<T>, MessageSourceAware {
|
||||
|
||||
private final ObservationRegistry registry;
|
||||
|
||||
@@ -53,19 +46,9 @@ public final class ObservationAuthorizationManager<T> implements AuthorizationMa
|
||||
|
||||
private MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||
|
||||
private MethodAuthorizationDeniedHandler handler = new ThrowingMethodAuthorizationDeniedHandler();
|
||||
|
||||
private MethodAuthorizationDeniedPostProcessor postProcessor = new ThrowingMethodAuthorizationDeniedPostProcessor();
|
||||
|
||||
public ObservationAuthorizationManager(ObservationRegistry registry, AuthorizationManager<T> delegate) {
|
||||
this.registry = registry;
|
||||
this.delegate = delegate;
|
||||
if (delegate instanceof MethodAuthorizationDeniedHandler h) {
|
||||
this.handler = h;
|
||||
}
|
||||
if (delegate instanceof MethodAuthorizationDeniedPostProcessor p) {
|
||||
this.postProcessor = p;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,15 +98,4 @@ public final class ObservationAuthorizationManager<T> implements AuthorizationMa
|
||||
this.messages = new MessageSourceAccessor(messageSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(MethodInvocation methodInvocation, AuthorizationResult authorizationResult) {
|
||||
return this.handler.handle(methodInvocation, authorizationResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessResult(MethodInvocationResult methodInvocationResult,
|
||||
AuthorizationResult authorizationResult) {
|
||||
return this.postProcessor.postProcessResult(methodInvocationResult, authorizationResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,15 +20,9 @@ import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationConvention;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authorization.method.MethodAuthorizationDeniedHandler;
|
||||
import org.springframework.security.authorization.method.MethodAuthorizationDeniedPostProcessor;
|
||||
import org.springframework.security.authorization.method.MethodInvocationResult;
|
||||
import org.springframework.security.authorization.method.ThrowingMethodAuthorizationDeniedHandler;
|
||||
import org.springframework.security.authorization.method.ThrowingMethodAuthorizationDeniedPostProcessor;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -38,8 +32,7 @@ import org.springframework.util.Assert;
|
||||
* @author Josh Cummings
|
||||
* @since 6.0
|
||||
*/
|
||||
public final class ObservationReactiveAuthorizationManager<T> implements ReactiveAuthorizationManager<T>,
|
||||
MethodAuthorizationDeniedHandler, MethodAuthorizationDeniedPostProcessor {
|
||||
public final class ObservationReactiveAuthorizationManager<T> implements ReactiveAuthorizationManager<T> {
|
||||
|
||||
private final ObservationRegistry registry;
|
||||
|
||||
@@ -47,20 +40,10 @@ public final class ObservationReactiveAuthorizationManager<T> implements Reactiv
|
||||
|
||||
private ObservationConvention<AuthorizationObservationContext<?>> convention = new AuthorizationObservationConvention();
|
||||
|
||||
private MethodAuthorizationDeniedHandler handler = new ThrowingMethodAuthorizationDeniedHandler();
|
||||
|
||||
private MethodAuthorizationDeniedPostProcessor postProcessor = new ThrowingMethodAuthorizationDeniedPostProcessor();
|
||||
|
||||
public ObservationReactiveAuthorizationManager(ObservationRegistry registry,
|
||||
ReactiveAuthorizationManager<T> delegate) {
|
||||
this.registry = registry;
|
||||
this.delegate = delegate;
|
||||
if (delegate instanceof MethodAuthorizationDeniedHandler h) {
|
||||
this.handler = h;
|
||||
}
|
||||
if (delegate instanceof MethodAuthorizationDeniedPostProcessor p) {
|
||||
this.postProcessor = p;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,15 +81,4 @@ public final class ObservationReactiveAuthorizationManager<T> implements Reactiv
|
||||
this.convention = convention;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(MethodInvocation methodInvocation, AuthorizationResult authorizationResult) {
|
||||
return this.handler.handle(methodInvocation, authorizationResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessResult(MethodInvocationResult methodInvocationResult,
|
||||
AuthorizationResult authorizationResult) {
|
||||
return this.postProcessor.postProcessResult(methodInvocationResult, authorizationResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ public final class AuthorizationManagerAfterMethodInterceptor implements Authori
|
||||
}
|
||||
|
||||
private Object postProcess(MethodInvocationResult mi, AuthorizationDecision decision) {
|
||||
if (this.authorizationManager instanceof MethodAuthorizationDeniedPostProcessor postProcessableDecision) {
|
||||
if (decision instanceof MethodAuthorizationDeniedPostProcessor postProcessableDecision) {
|
||||
return postProcessableDecision.postProcessResult(mi, decision);
|
||||
}
|
||||
return this.defaultPostProcessor.postProcessResult(mi, decision);
|
||||
|
||||
@@ -159,7 +159,7 @@ public final class AuthorizationManagerAfterReactiveMethodInterceptor implements
|
||||
return Mono.just(methodInvocationResult.getResult());
|
||||
}
|
||||
return Mono.fromSupplier(() -> {
|
||||
if (this.authorizationManager instanceof MethodAuthorizationDeniedPostProcessor postProcessableDecision) {
|
||||
if (decision instanceof MethodAuthorizationDeniedPostProcessor postProcessableDecision) {
|
||||
return postProcessableDecision.postProcessResult(methodInvocationResult, decision);
|
||||
}
|
||||
return this.defaultPostProcessor.postProcessResult(methodInvocationResult, decision);
|
||||
|
||||
@@ -257,7 +257,7 @@ public final class AuthorizationManagerBeforeMethodInterceptor implements Author
|
||||
}
|
||||
|
||||
private Object handle(MethodInvocation mi, AuthorizationDecision decision) {
|
||||
if (this.authorizationManager instanceof MethodAuthorizationDeniedHandler handler) {
|
||||
if (decision instanceof MethodAuthorizationDeniedHandler handler) {
|
||||
return handler.handle(mi, decision);
|
||||
}
|
||||
return this.defaultHandler.handle(mi, decision);
|
||||
|
||||
@@ -162,7 +162,7 @@ public final class AuthorizationManagerBeforeReactiveMethodInterceptor implement
|
||||
|
||||
private Mono<Object> postProcess(AuthorizationDecision decision, MethodInvocation mi) {
|
||||
return Mono.fromSupplier(() -> {
|
||||
if (this.authorizationManager instanceof MethodAuthorizationDeniedHandler handler) {
|
||||
if (decision instanceof MethodAuthorizationDeniedHandler handler) {
|
||||
return handler.handle(mi, decision);
|
||||
}
|
||||
return this.defaultHandler.handle(mi, decision);
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 org.springframework.expression.Expression;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.authorization.ExpressionAuthorizationDecision;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
class PostAuthorizeAuthorizationDecision extends ExpressionAuthorizationDecision
|
||||
implements MethodAuthorizationDeniedPostProcessor {
|
||||
|
||||
private final MethodAuthorizationDeniedPostProcessor postProcessor;
|
||||
|
||||
PostAuthorizeAuthorizationDecision(boolean granted, Expression expression,
|
||||
MethodAuthorizationDeniedPostProcessor postProcessor) {
|
||||
super(granted, expression);
|
||||
Assert.notNull(postProcessor, "postProcessor cannot be null");
|
||||
this.postProcessor = postProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessResult(MethodInvocationResult methodInvocationResult, AuthorizationResult result) {
|
||||
return this.postProcessor.postProcessResult(methodInvocationResult, result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,7 +27,6 @@ import org.springframework.security.access.expression.method.MethodSecurityExpre
|
||||
import org.springframework.security.access.prepost.PostAuthorize;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
/**
|
||||
@@ -38,8 +37,7 @@ import org.springframework.security.core.Authentication;
|
||||
* @author Evgeniy Cheban
|
||||
* @since 5.6
|
||||
*/
|
||||
public final class PostAuthorizeAuthorizationManager
|
||||
implements AuthorizationManager<MethodInvocationResult>, MethodAuthorizationDeniedPostProcessor {
|
||||
public final class PostAuthorizeAuthorizationManager implements AuthorizationManager<MethodInvocationResult> {
|
||||
|
||||
private PostAuthorizeExpressionAttributeRegistry registry = new PostAuthorizeExpressionAttributeRegistry();
|
||||
|
||||
@@ -90,18 +88,13 @@ public final class PostAuthorizeAuthorizationManager
|
||||
if (attribute == ExpressionAttribute.NULL_ATTRIBUTE) {
|
||||
return null;
|
||||
}
|
||||
PostAuthorizeExpressionAttribute postAuthorizeAttribute = (PostAuthorizeExpressionAttribute) attribute;
|
||||
MethodSecurityExpressionHandler expressionHandler = this.registry.getExpressionHandler();
|
||||
EvaluationContext ctx = expressionHandler.createEvaluationContext(authentication, mi.getMethodInvocation());
|
||||
expressionHandler.setReturnObject(mi.getResult(), ctx);
|
||||
return (AuthorizationDecision) ExpressionUtils.evaluate(attribute.getExpression(), ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessResult(MethodInvocationResult methodInvocationResult,
|
||||
AuthorizationResult authorizationResult) {
|
||||
ExpressionAttribute attribute = this.registry.getAttribute(methodInvocationResult.getMethodInvocation());
|
||||
PostAuthorizeExpressionAttribute postAuthorizeAttribute = (PostAuthorizeExpressionAttribute) attribute;
|
||||
return postAuthorizeAttribute.getPostProcessor().postProcessResult(methodInvocationResult, authorizationResult);
|
||||
boolean granted = ExpressionUtils.evaluateAsBoolean(postAuthorizeAttribute.getExpression(), ctx);
|
||||
return new PostAuthorizeAuthorizationDecision(granted, postAuthorizeAttribute.getExpression(),
|
||||
postAuthorizeAttribute.getPostProcessor());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.springframework.security.access.expression.method.DefaultMethodSecuri
|
||||
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
||||
import org.springframework.security.access.prepost.PostAuthorize;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.authorization.ReactiveAuthorizationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -38,7 +37,7 @@ import org.springframework.util.Assert;
|
||||
* @since 5.8
|
||||
*/
|
||||
public final class PostAuthorizeReactiveAuthorizationManager
|
||||
implements ReactiveAuthorizationManager<MethodInvocationResult>, MethodAuthorizationDeniedPostProcessor {
|
||||
implements ReactiveAuthorizationManager<MethodInvocationResult> {
|
||||
|
||||
private final PostAuthorizeExpressionAttributeRegistry registry = new PostAuthorizeExpressionAttributeRegistry();
|
||||
|
||||
@@ -83,23 +82,15 @@ public final class PostAuthorizeReactiveAuthorizationManager
|
||||
if (attribute == ExpressionAttribute.NULL_ATTRIBUTE) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
PostAuthorizeExpressionAttribute postAuthorizeAttribute = (PostAuthorizeExpressionAttribute) attribute;
|
||||
MethodSecurityExpressionHandler expressionHandler = this.registry.getExpressionHandler();
|
||||
// @formatter:off
|
||||
return authentication
|
||||
.map((auth) -> expressionHandler.createEvaluationContext(auth, mi))
|
||||
.doOnNext((ctx) -> expressionHandler.setReturnObject(result.getResult(), ctx))
|
||||
.flatMap((ctx) -> ReactiveExpressionUtils.evaluate(attribute.getExpression(), ctx))
|
||||
.cast(AuthorizationDecision.class);
|
||||
.flatMap((ctx) -> ReactiveExpressionUtils.evaluateAsBoolean(attribute.getExpression(), ctx))
|
||||
.map((granted) -> new PostAuthorizeAuthorizationDecision(granted, postAuthorizeAttribute.getExpression(), postAuthorizeAttribute.getPostProcessor()));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessResult(MethodInvocationResult methodInvocationResult,
|
||||
AuthorizationResult authorizationResult) {
|
||||
ExpressionAttribute attribute = this.registry.getAttribute(methodInvocationResult.getMethodInvocation());
|
||||
PostAuthorizeExpressionAttribute postAuthorizeAttribute = (PostAuthorizeExpressionAttribute) attribute;
|
||||
return postAuthorizeAttribute.getPostProcessor().postProcessResult(methodInvocationResult, authorizationResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.authorization.ExpressionAuthorizationDecision;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
class PreAuthorizeAuthorizationDecision extends ExpressionAuthorizationDecision
|
||||
implements MethodAuthorizationDeniedHandler {
|
||||
|
||||
private final MethodAuthorizationDeniedHandler handler;
|
||||
|
||||
PreAuthorizeAuthorizationDecision(boolean granted, Expression expression,
|
||||
MethodAuthorizationDeniedHandler handler) {
|
||||
super(granted, expression);
|
||||
Assert.notNull(handler, "handler cannot be null");
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(MethodInvocation methodInvocation, AuthorizationResult result) {
|
||||
return this.handler.handle(methodInvocation, result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,7 +27,6 @@ import org.springframework.security.access.expression.method.MethodSecurityExpre
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
/**
|
||||
@@ -38,8 +37,7 @@ import org.springframework.security.core.Authentication;
|
||||
* @author Evgeniy Cheban
|
||||
* @since 5.6
|
||||
*/
|
||||
public final class PreAuthorizeAuthorizationManager
|
||||
implements AuthorizationManager<MethodInvocation>, MethodAuthorizationDeniedHandler {
|
||||
public final class PreAuthorizeAuthorizationManager implements AuthorizationManager<MethodInvocation> {
|
||||
|
||||
private PreAuthorizeExpressionAttributeRegistry registry = new PreAuthorizeExpressionAttributeRegistry();
|
||||
|
||||
@@ -82,15 +80,11 @@ public final class PreAuthorizeAuthorizationManager
|
||||
if (attribute == ExpressionAttribute.NULL_ATTRIBUTE) {
|
||||
return null;
|
||||
}
|
||||
PreAuthorizeExpressionAttribute preAuthorizeAttribute = (PreAuthorizeExpressionAttribute) attribute;
|
||||
EvaluationContext ctx = this.registry.getExpressionHandler().createEvaluationContext(authentication, mi);
|
||||
return (AuthorizationDecision) ExpressionUtils.evaluate(attribute.getExpression(), ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(MethodInvocation methodInvocation, AuthorizationResult authorizationResult) {
|
||||
ExpressionAttribute attribute = this.registry.getAttribute(methodInvocation);
|
||||
PreAuthorizeExpressionAttribute postAuthorizeAttribute = (PreAuthorizeExpressionAttribute) attribute;
|
||||
return postAuthorizeAttribute.getHandler().handle(methodInvocation, authorizationResult);
|
||||
boolean granted = ExpressionUtils.evaluateAsBoolean(preAuthorizeAttribute.getExpression(), ctx);
|
||||
return new PreAuthorizeAuthorizationDecision(granted, preAuthorizeAttribute.getExpression(),
|
||||
preAuthorizeAttribute.getHandler());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.springframework.security.access.expression.method.DefaultMethodSecuri
|
||||
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.authorization.ReactiveAuthorizationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -37,8 +36,7 @@ import org.springframework.util.Assert;
|
||||
* @author Evgeniy Cheban
|
||||
* @since 5.8
|
||||
*/
|
||||
public final class PreAuthorizeReactiveAuthorizationManager
|
||||
implements ReactiveAuthorizationManager<MethodInvocation>, MethodAuthorizationDeniedHandler {
|
||||
public final class PreAuthorizeReactiveAuthorizationManager implements ReactiveAuthorizationManager<MethodInvocation> {
|
||||
|
||||
private final PreAuthorizeExpressionAttributeRegistry registry = new PreAuthorizeExpressionAttributeRegistry();
|
||||
|
||||
@@ -81,19 +79,13 @@ public final class PreAuthorizeReactiveAuthorizationManager
|
||||
if (attribute == ExpressionAttribute.NULL_ATTRIBUTE) {
|
||||
return Mono.empty();
|
||||
}
|
||||
PreAuthorizeExpressionAttribute preAuthorizeAttribute = (PreAuthorizeExpressionAttribute) attribute;
|
||||
// @formatter:off
|
||||
return authentication
|
||||
.map((auth) -> this.registry.getExpressionHandler().createEvaluationContext(auth, mi))
|
||||
.flatMap((ctx) -> ReactiveExpressionUtils.evaluate(attribute.getExpression(), ctx))
|
||||
.cast(AuthorizationDecision.class);
|
||||
.flatMap((ctx) -> ReactiveExpressionUtils.evaluateAsBoolean(attribute.getExpression(), ctx))
|
||||
.map((granted) -> new PreAuthorizeAuthorizationDecision(granted, preAuthorizeAttribute.getExpression(), preAuthorizeAttribute.getHandler()));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(MethodInvocation methodInvocation, AuthorizationResult authorizationResult) {
|
||||
ExpressionAttribute attribute = this.registry.getAttribute(methodInvocation);
|
||||
PreAuthorizeExpressionAttribute preAuthorizeAttribute = (PreAuthorizeExpressionAttribute) attribute;
|
||||
return preAuthorizeAttribute.getHandler().handle(methodInvocation, authorizationResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,8 +21,6 @@ import reactor.core.publisher.Mono;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.security.authorization.AuthorizationResult;
|
||||
import org.springframework.security.authorization.ExpressionAuthorizationDecision;
|
||||
|
||||
/**
|
||||
* For internal use only, as this contract is likely to change.
|
||||
@@ -32,33 +30,6 @@ import org.springframework.security.authorization.ExpressionAuthorizationDecisio
|
||||
*/
|
||||
final class ReactiveExpressionUtils {
|
||||
|
||||
static Mono<AuthorizationResult> evaluate(Expression expr, EvaluationContext ctx) {
|
||||
return Mono.defer(() -> {
|
||||
Object value;
|
||||
try {
|
||||
value = expr.getValue(ctx);
|
||||
}
|
||||
catch (EvaluationException ex) {
|
||||
return Mono.error(() -> new IllegalArgumentException(
|
||||
"Failed to evaluate expression '" + expr.getExpressionString() + "'", ex));
|
||||
}
|
||||
if (value instanceof Mono<?> mono) {
|
||||
return mono.flatMap((data) -> adapt(expr, data));
|
||||
}
|
||||
return adapt(expr, value);
|
||||
});
|
||||
}
|
||||
|
||||
private static Mono<AuthorizationResult> adapt(Expression expr, Object value) {
|
||||
if (value instanceof Boolean granted) {
|
||||
return Mono.just(new ExpressionAuthorizationDecision(granted, expr));
|
||||
}
|
||||
if (value instanceof AuthorizationResult decision) {
|
||||
return Mono.just(decision);
|
||||
}
|
||||
return createInvalidReturnTypeMono(expr);
|
||||
}
|
||||
|
||||
static Mono<Boolean> evaluateAsBoolean(Expression expr, EvaluationContext ctx) {
|
||||
return Mono.defer(() -> {
|
||||
Object value;
|
||||
@@ -85,9 +56,9 @@ final class ReactiveExpressionUtils {
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> Mono<T> createInvalidReturnTypeMono(Expression expr) {
|
||||
return Mono.error(() -> new IllegalStateException("Expression: '" + expr.getExpressionString()
|
||||
+ "' must return boolean, Mono<Boolean>, AuthorizationResult, or Mono<AuthorizationResult>"));
|
||||
private static Mono<Boolean> createInvalidReturnTypeMono(Expression expr) {
|
||||
return Mono.error(() -> new IllegalStateException(
|
||||
"Expression: '" + expr.getExpressionString() + "' must return boolean or Mono<Boolean>"));
|
||||
}
|
||||
|
||||
private ReactiveExpressionUtils() {
|
||||
|
||||
@@ -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