@ -16,8 +16,11 @@
@@ -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;
@@ -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
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 ) ;
}
}
}