如何动态配置Spring AOP

问题描述 投票:0回答:1

现在程序运行时需要向spring容器中添加一个bean。这个bean就是spring AOP的配置类。如何让配置生效。

我知道@Component注解一般情况下需要配置,但是我需要在运行时配置,而不是在启动时扫描配置

一开始我是这样写的

    @Aspect
    public class ParamAspect {
    
        private static String result;
    
        @Pointcut("execution(public * com.example.aop.*.*(String))")
        public void doOperation() {...}
    
    
        @Before("doOperation()")
        public void before(JoinPoint joinPoint) throws Exception {...}

    
        @AfterReturning(returning = "object", pointcut = "doOperation()")
        public void doAfterReturning(Object object) {...}
    }

注册bean

        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) beanFactoryField.get(ctx);

        BeanDefinitionRegistry beanDefReg = beanFactory;
        BeanDefinitionBuilder beanDefBuilder = BeanDefinitionBuilder.genericBeanDefinition(ParamAspect.class);
        BeanDefinition beanDef = beanDefBuilder.getBeanDefinition();
        if (!beanDefReg.containsBeanDefinition("theBean")) {
            beanDefReg.registerBeanDefinition("theBean", beanDef);
        }

但我发现这不起作用 然后我就尝试一下网上提供的方法

public class Config {
    private Advisor config(){
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution(public * com.example.aop.*.*(String))");
        return   new DefaultPointcutAdvisor(pointcut, new MyMethodInterceptor());
    }
}

public class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
    ...
    }
}

并换班级

        BeanDefinitionBuilder beanDefBuilder = BeanDefinitionBuilder.genericBeanDefinition(Config.class);

还是不行

我从事Java安全研究,想找到一种动态配置AOP来执行恶意代码的方法。所以想找到一种方法,在注册AOP配置的bean后,让AOP生效。

如果应用存在反序列化漏洞,黑客可以通过恶意构造的对象触发注册AOP的功能,进而执行恶意代码。

java spring spring-boot spring-aop
1个回答
1
投票

您的

private Advisor config()
应该是
@Bean public Advisor config()
,那么它就可以工作,但仅限于连接应用程序时。

请参阅 GitHub 上的这段代码作为示例,我在这个答案的更新 3 中使用了该示例。您可以克隆该项目并进行试验。

另一个例子可以在这个问题中找到。您只需应用我的答案中的更正即可使其发挥作用。

我不认为它比这更有活力,但我绝不是 Spring 专家。

请注意,“final class MyClass”是一个破坏性的因素。请参阅下面的“!within”,如下所示:https://stackoverflow.com/a/26714132/214977

配置示例:

import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;

@Bean
public Advisor addAopAdvisor() {
   AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
   /* define with some package names and VERY IMPORTANT
    ... (not) any "final class".
    aop's main "trick" is to subclass an existing class to create the wrapper proxy.
    */
   pointcut.setExpression("(within(com.me.packagename1..*) || within(com.me.packagename2..*)) && !within(is(FinalType))");
   return new DefaultPointcutAdvisor(pointcut, new MyPerformanceMonitorInterceptor());
}
 
© www.soinside.com 2019 - 2024. All rights reserved.