@ -16,22 +16,17 @@
@@ -16,22 +16,17 @@
package org.springframework.security.config.annotation.method.configuration ;
import java.util.function.Consumer ;
import java.util.function.Supplier ;
import io.micrometer.observation.ObservationRegistry ;
import org.aopalliance.aop.Advice ;
import org.aopalliance.intercept.MethodInterceptor ;
import org.aopalliance.intercept.MethodInvocation ;
import org.jetbrains.annotations.NotNull ;
import org.jetbrains.annotations.Nullable ;
import org.springframework.aop.Pointcut ;
import org.springframework.aop.framework.AopInfrastructureBean ;
import org.springframework.beans.BeansException ;
import org.springframework.beans.factory.ObjectProvider ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.beans.factory.config.BeanDefinition ;
import org.springframework.context.ApplicationContext ;
import org.springframework.context.ApplicationContextAware ;
import org.springframework.context.annotation.Bean ;
import org.springframework.context.annotation.Configuration ;
import org.springframework.context.annotation.Fallback ;
@ -39,18 +34,15 @@ import org.springframework.context.annotation.Role;
@@ -39,18 +34,15 @@ import org.springframework.context.annotation.Role;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler ;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler ;
import org.springframework.security.authentication.ReactiveAuthenticationManager ;
import org.springframework.security.authorization.ReactiveAuthorizationManager ;
import org.springframework.security.authorization.method.AuthorizationAdvisor ;
import org.springframework.security.authorization.ObservationReactiveAuthorizationManager ;
import org.springframework.security.authorization.method.AuthorizationManagerAfterReactiveMethodInterceptor ;
import org.springframework.security.authorization.method.AuthorizationManagerBeforeReactiveMethodInterceptor ;
import org.springframework.security.authorization.method.MethodInvocationResult ;
import org.springframework.security.authorization.method.PostAuthorizeReactiveAuthorizationManager ;
import org.springframework.security.authorization.method.PostFilterAuthorizationReactiveMethodInterceptor ;
import org.springframework.security.authorization.method.PreAuthorizeReactiveAuthorizationManager ;
import org.springframework.security.authorization.method.PreFilterAuthorizationReactiveMethodInterceptor ;
import org.springframework.security.authorization.method.PrePostTemplateDefaults ;
import org.springframework.security.config.core.GrantedAuthorityDefaults ;
import org.springframework.util.function.SingletonSupplier ;
/ * *
* Configuration for a { @link ReactiveAuthenticationManager } based Method Security .
@ -58,59 +50,105 @@ import org.springframework.util.function.SingletonSupplier;
@@ -58,59 +50,105 @@ import org.springframework.util.function.SingletonSupplier;
* @author Evgeniy Cheban
* @since 5 . 8
* /
@Configuration ( proxyBeanMethods = false )
final class ReactiveAuthorizationManagerMethodSecurityConfiguration implements AopInfrastructureBean {
@Configuration ( value = "_reactiveMethodSecurityConfiguration" , proxyBeanMethods = false )
final class ReactiveAuthorizationManagerMethodSecurityConfiguration
implements AopInfrastructureBean , ApplicationContextAware {
private static final Pointcut preFilterPointcut = new PreFilterAuthorizationReactiveMethodInterceptor ( )
. getPointcut ( ) ;
private static final Pointcut preAuthorizePointcut = AuthorizationManagerBeforeReactiveMethodInterceptor
. preAuthorize ( )
. getPointcut ( ) ;
private static final Pointcut postAuthorizePointcut = AuthorizationManagerAfterReactiveMethodInterceptor
. postAuthorize ( )
. getPointcut ( ) ;
private static final Pointcut postFilterPointcut = new PostFilterAuthorizationReactiveMethodInterceptor ( )
. getPointcut ( ) ;
private PreFilterAuthorizationReactiveMethodInterceptor preFilterMethodInterceptor = new PreFilterAuthorizationReactiveMethodInterceptor ( ) ;
private PreAuthorizeReactiveAuthorizationManager preAuthorizeAuthorizationManager = new PreAuthorizeReactiveAuthorizationManager ( ) ;
private PostAuthorizeReactiveAuthorizationManager postAuthorizeAuthorizationManager = new PostAuthorizeReactiveAuthorizationManager ( ) ;
private PostFilterAuthorizationReactiveMethodInterceptor postFilterMethodInterceptor = new PostFilterAuthorizationReactiveMethodInterceptor ( ) ;
private AuthorizationManagerBeforeReactiveMethodInterceptor preAuthorizeMethodInterceptor ;
private AuthorizationManagerAfterReactiveMethodInterceptor postAuthorizeMethodInterceptor ;
@Autowired ( required = false )
ReactiveAuthorizationManagerMethodSecurityConfiguration ( MethodSecurityExpressionHandler expressionHandler ) {
if ( expressionHandler ! = null ) {
this . preFilterMethodInterceptor = new PreFilterAuthorizationReactiveMethodInterceptor ( expressionHandler ) ;
this . preAuthorizeAuthorizationManager = new PreAuthorizeReactiveAuthorizationManager ( expressionHandler ) ;
this . postFilterMethodInterceptor = new PostFilterAuthorizationReactiveMethodInterceptor ( expressionHandler ) ;
this . postAuthorizeAuthorizationManager = new PostAuthorizeReactiveAuthorizationManager ( expressionHandler ) ;
}
this . preAuthorizeMethodInterceptor = AuthorizationManagerBeforeReactiveMethodInterceptor
. preAuthorize ( this . preAuthorizeAuthorizationManager ) ;
this . postAuthorizeMethodInterceptor = AuthorizationManagerAfterReactiveMethodInterceptor
. postAuthorize ( this . postAuthorizeAuthorizationManager ) ;
}
@Override
public void setApplicationContext ( ApplicationContext context ) throws BeansException {
this . preAuthorizeAuthorizationManager . setApplicationContext ( context ) ;
this . postAuthorizeAuthorizationManager . setApplicationContext ( context ) ;
}
@Autowired ( required = false )
void setTemplateDefaults ( PrePostTemplateDefaults templateDefaults ) {
this . preFilterMethodInterceptor . setTemplateDefaults ( templateDefaults ) ;
this . preAuthorizeAuthorizationManager . setTemplateDefaults ( templateDefaults ) ;
this . postAuthorizeAuthorizationManager . setTemplateDefaults ( templateDefaults ) ;
this . postFilterMethodInterceptor . setTemplateDefaults ( templateDefaults ) ;
}
@Autowired ( required = false )
void setObservationRegistry ( ObservationRegistry registry ) {
if ( registry . isNoop ( ) ) {
return ;
}
this . preAuthorizeMethodInterceptor = AuthorizationManagerBeforeReactiveMethodInterceptor . preAuthorize (
new ObservationReactiveAuthorizationManager < > ( registry , this . preAuthorizeAuthorizationManager ) ) ;
this . postAuthorizeMethodInterceptor = AuthorizationManagerAfterReactiveMethodInterceptor . postAuthorize (
new ObservationReactiveAuthorizationManager < > ( registry , this . postAuthorizeAuthorizationManager ) ) ;
}
@Bean
@Role ( BeanDefinition . ROLE_INFRASTRUCTURE )
static MethodInterceptor preFilterAuthorizationMethodInterceptor ( MethodSecurityExpressionHandler expressionHandler ,
ObjectProvider < PrePostTemplateDefaults > defaultsObjectProvider ) {
PreFilterAuthorizationReactiveMethodInterceptor interceptor = new PreFilterAuthorizationReactiveMethodInterceptor (
expressionHandler ) ;
return new DeferringMethodInterceptor < > ( interceptor ,
( i ) - > defaultsObjectProvider . ifAvailable ( i : : setTemplateDefaults ) ) ;
static MethodInterceptor preFilterAuthorizationMethodInterceptor (
ObjectProvider < ReactiveAuthorizationManagerMethodSecurityConfiguration > _reactiveMethodSecurityConfiguration ) {
return new DeferringMethodInterceptor < > ( preFilterPointcut ,
( ) - > _reactiveMethodSecurityConfiguration . getObject ( ) . preFilterMethodInterceptor ) ;
}
@Bean
@Role ( BeanDefinition . ROLE_INFRASTRUCTURE )
static MethodInterceptor preAuthorizeAuthorizationMethodInterceptor (
MethodSecurityExpressionHandler expressionHandler ,
ObjectProvider < PrePostTemplateDefaults > defaultsObjectProvider ,
ObjectProvider < ObservationRegistry > registryProvider , ApplicationContext context ) {
PreAuthorizeReactiveAuthorizationManager manager = new PreAuthorizeReactiveAuthorizationManager (
expressionHandler ) ;
manager . setApplicationContext ( context ) ;
ReactiveAuthorizationManager < MethodInvocation > authorizationManager = manager ( manager , registryProvider ) ;
AuthorizationAdvisor interceptor = AuthorizationManagerBeforeReactiveMethodInterceptor
. preAuthorize ( authorizationManager ) ;
return new DeferringMethodInterceptor < > ( interceptor ,
( i ) - > defaultsObjectProvider . ifAvailable ( manager : : setTemplateDefaults ) ) ;
ObjectProvider < ReactiveAuthorizationManagerMethodSecurityConfiguration > _reactiveMethodSecurityConfiguration ) {
return new DeferringMethodInterceptor < > ( preAuthorizePointcut ,
( ) - > _reactiveMethodSecurityConfiguration . getObject ( ) . preAuthorizeMethodInterceptor ) ;
}
@Bean
@Role ( BeanDefinition . ROLE_INFRASTRUCTURE )
static MethodInterceptor postFilterAuthorizationMethodInterceptor ( MethodSecurityExpressionHandler expressionHandler ,
ObjectProvider < PrePostTemplateDefaults > defaultsObjectProvider ) {
PostFilterAuthorizationReactiveMethodInterceptor interceptor = new PostFilterAuthorizationReactiveMethodInterceptor (
expressionHandler ) ;
return new DeferringMethodInterceptor < > ( interceptor ,
( i ) - > defaultsObjectProvider . ifAvailable ( i : : setTemplateDefaults ) ) ;
static MethodInterceptor postFilterAuthorizationMethodInterceptor (
ObjectProvider < ReactiveAuthorizationManagerMethodSecurityConfiguration > _reactiveMethodSecurityConfiguration ) {
return new DeferringMethodInterceptor < > ( postFilterPointcut ,
( ) - > _reactiveMethodSecurityConfiguration . getObject ( ) . postFilterMethodInterceptor ) ;
}
@Bean
@Role ( BeanDefinition . ROLE_INFRASTRUCTURE )
static MethodInterceptor postAuthorizeAuthorizationMethodInterceptor (
MethodSecurityExpressionHandler expressionHandler ,
ObjectProvider < PrePostTemplateDefaults > defaultsObjectProvider ,
ObjectProvider < ObservationRegistry > registryProvider , ApplicationContext context ) {
PostAuthorizeReactiveAuthorizationManager manager = new PostAuthorizeReactiveAuthorizationManager (
expressionHandler ) ;
manager . setApplicationContext ( context ) ;
ReactiveAuthorizationManager < MethodInvocationResult > authorizationManager = manager ( manager , registryProvider ) ;
AuthorizationAdvisor interceptor = AuthorizationManagerAfterReactiveMethodInterceptor
. postAuthorize ( authorizationManager ) ;
return new DeferringMethodInterceptor < > ( interceptor ,
( i ) - > defaultsObjectProvider . ifAvailable ( manager : : setTemplateDefaults ) ) ;
ObjectProvider < ReactiveAuthorizationManagerMethodSecurityConfiguration > _reactiveMethodSecurityConfiguration ) {
return new DeferringMethodInterceptor < > ( postAuthorizePointcut ,
( ) - > _reactiveMethodSecurityConfiguration . getObject ( ) . postAuthorizeMethodInterceptor ) ;
}
@Bean
@ -125,55 +163,4 @@ final class ReactiveAuthorizationManagerMethodSecurityConfiguration implements A
@@ -125,55 +163,4 @@ final class ReactiveAuthorizationManagerMethodSecurityConfiguration implements A
return handler ;
}
static < T > ReactiveAuthorizationManager < T > manager ( ReactiveAuthorizationManager < T > delegate ,
ObjectProvider < ObservationRegistry > registryProvider ) {
return new DeferringObservationReactiveAuthorizationManager < > ( registryProvider , delegate ) ;
}
private static final class DeferringMethodInterceptor < M extends AuthorizationAdvisor >
implements AuthorizationAdvisor {
private final Pointcut pointcut ;
private final int order ;
private final Supplier < M > delegate ;
DeferringMethodInterceptor ( M delegate , Consumer < M > supplier ) {
this . pointcut = delegate . getPointcut ( ) ;
this . order = delegate . getOrder ( ) ;
this . delegate = SingletonSupplier . of ( ( ) - > {
supplier . accept ( delegate ) ;
return delegate ;
} ) ;
}
@Nullable
@Override
public Object invoke ( @NotNull MethodInvocation invocation ) throws Throwable {
return this . delegate . get ( ) . invoke ( invocation ) ;
}
@Override
public Pointcut getPointcut ( ) {
return this . pointcut ;
}
@Override
public Advice getAdvice ( ) {
return this ;
}
@Override
public int getOrder ( ) {
return this . order ;
}
@Override
public boolean isPerInstance ( ) {
return true ;
}
}
}