|
@@ -16,8 +16,11 @@
|
|
|
|
|
|
package org.springframework.security.config.annotation.method.configuration;
|
|
|
|
|
|
+import java.util.function.Supplier;
|
|
|
+
|
|
|
import io.micrometer.observation.ObservationRegistry;
|
|
|
import org.aopalliance.intercept.MethodInterceptor;
|
|
|
+import org.aopalliance.intercept.MethodInvocation;
|
|
|
|
|
|
import org.springframework.beans.factory.ObjectProvider;
|
|
|
import org.springframework.beans.factory.config.BeanDefinition;
|
|
@@ -25,6 +28,9 @@ import org.springframework.context.ApplicationContext;
|
|
|
import org.springframework.context.annotation.Bean;
|
|
|
import org.springframework.context.annotation.Configuration;
|
|
|
import org.springframework.context.annotation.Role;
|
|
|
+import org.springframework.expression.EvaluationContext;
|
|
|
+import org.springframework.expression.Expression;
|
|
|
+import org.springframework.expression.ExpressionParser;
|
|
|
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
|
|
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
|
|
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
|
@@ -36,7 +42,9 @@ import org.springframework.security.authorization.method.PostFilterAuthorization
|
|
|
import org.springframework.security.authorization.method.PreAuthorizeAuthorizationManager;
|
|
|
import org.springframework.security.authorization.method.PreFilterAuthorizationMethodInterceptor;
|
|
|
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
|
|
+import org.springframework.security.core.Authentication;
|
|
|
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
|
|
+import org.springframework.util.function.SingletonSupplier;
|
|
|
|
|
|
/**
|
|
|
* Base {@link Configuration} for enabling Spring Security Method Security.
|
|
@@ -59,7 +67,7 @@ final class PrePostMethodSecurityConfiguration {
|
|
|
PreFilterAuthorizationMethodInterceptor preFilter = new PreFilterAuthorizationMethodInterceptor();
|
|
|
strategyProvider.ifAvailable(preFilter::setSecurityContextHolderStrategy);
|
|
|
preFilter.setExpressionHandler(
|
|
|
- expressionHandlerProvider.getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, context)));
|
|
|
+ new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
|
|
|
return preFilter;
|
|
|
}
|
|
|
|
|
@@ -73,7 +81,7 @@ final class PrePostMethodSecurityConfiguration {
|
|
|
ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
|
|
|
PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager();
|
|
|
manager.setExpressionHandler(
|
|
|
- expressionHandlerProvider.getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, context)));
|
|
|
+ new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
|
|
|
AuthorizationManagerBeforeMethodInterceptor preAuthorize = AuthorizationManagerBeforeMethodInterceptor
|
|
|
.preAuthorize(manager(manager, registryProvider));
|
|
|
strategyProvider.ifAvailable(preAuthorize::setSecurityContextHolderStrategy);
|
|
@@ -91,7 +99,7 @@ final class PrePostMethodSecurityConfiguration {
|
|
|
ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
|
|
|
PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager();
|
|
|
manager.setExpressionHandler(
|
|
|
- expressionHandlerProvider.getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, context)));
|
|
|
+ new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
|
|
|
AuthorizationManagerAfterMethodInterceptor postAuthorize = AuthorizationManagerAfterMethodInterceptor
|
|
|
.postAuthorize(manager(manager, registryProvider));
|
|
|
strategyProvider.ifAvailable(postAuthorize::setSecurityContextHolderStrategy);
|
|
@@ -108,7 +116,7 @@ final class PrePostMethodSecurityConfiguration {
|
|
|
PostFilterAuthorizationMethodInterceptor postFilter = new PostFilterAuthorizationMethodInterceptor();
|
|
|
strategyProvider.ifAvailable(postFilter::setSecurityContextHolderStrategy);
|
|
|
postFilter.setExpressionHandler(
|
|
|
- expressionHandlerProvider.getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, context)));
|
|
|
+ new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
|
|
|
return postFilter;
|
|
|
}
|
|
|
|
|
@@ -125,4 +133,43 @@ final class PrePostMethodSecurityConfiguration {
|
|
|
return new DeferringObservationAuthorizationManager<>(registryProvider, delegate);
|
|
|
}
|
|
|
|
|
|
+ private static final class DeferringMethodSecurityExpressionHandler implements MethodSecurityExpressionHandler {
|
|
|
+
|
|
|
+ private final Supplier<MethodSecurityExpressionHandler> expressionHandler;
|
|
|
+
|
|
|
+ private DeferringMethodSecurityExpressionHandler(
|
|
|
+ ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
|
|
|
+ ObjectProvider<GrantedAuthorityDefaults> defaultsProvider, ApplicationContext applicationContext) {
|
|
|
+ this.expressionHandler = SingletonSupplier.of(() -> expressionHandlerProvider
|
|
|
+ .getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, applicationContext)));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ExpressionParser getExpressionParser() {
|
|
|
+ return this.expressionHandler.get().getExpressionParser();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public EvaluationContext createEvaluationContext(Authentication authentication, MethodInvocation invocation) {
|
|
|
+ return this.expressionHandler.get().createEvaluationContext(authentication, invocation);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public EvaluationContext createEvaluationContext(Supplier<Authentication> authentication,
|
|
|
+ MethodInvocation invocation) {
|
|
|
+ return this.expressionHandler.get().createEvaluationContext(authentication, invocation);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Object filter(Object filterTarget, Expression filterExpression, EvaluationContext ctx) {
|
|
|
+ return this.expressionHandler.get().filter(filterTarget, filterExpression, ctx);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void setReturnObject(Object returnObject, EvaluationContext ctx) {
|
|
|
+ this.expressionHandler.get().setReturnObject(returnObject, ctx);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
}
|