现在程序运行时需要向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的功能,进而执行恶意代码。
您的
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());
}