修改部分:对于3.0.4版本和3.0.7版本主要修改是org.springframework.cloud.gateway.supportShortcutConfigurable类中的
static Object getValue(SpelExpressionParser parser, BeanFactory beanFactory, String entryValue) {
Object value;
String rawValue = entryValue;
if (rawValue != null) {
rawValue = rawValue.trim();
}
if (rawValue != null && rawValue.startsWith("#{") && entryValue.endsWith("}")) {
// assume it's spel
GatewayEvaluationContext context = new GatewayEvaluationContext(beanFactory);
Expression expression = parser.parseExpression(entryValue, new TemplateParserContext());
value = expression.getValue(context);
}
else {
value = entryValue;
}
return value;
}
此处的GatewayEvaluationContext context = new GatewayEvaluationContext(beanFactory);之前使用的
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new BeanFactoryResolver(beanFactory));
GatewayEvaluationContext 实际上是对SimpleEvaluationContext的一个包装真实动作都是由SimpleEvaluationContext执行的并通过添加一个配置属性来决定是否启用属性的处理
spring.cloud.gateway.restrictive-property-accessor.enabled
默认是true即不允许访问
最后原因在于
StandardEvaluationContext类的TypeLocator使用StandardTypeLocator类,此类处理spel的时候会从java.lang包下搜索需要的类并执行其方法及参数
例子如下代码
package com.example.demo;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class HelloTest {
public static void main(String[] args) {
// EvaluationContext standardEvaluationContext = SimpleEvaluationContext.forReadOnlyDataBinding().build();
EvaluationContext standardEvaluationContext = new StandardEvaluationContext();
SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
Expression expression = spelExpressionParser.parseExpression("#{T(java.lang.Runtime).getRuntime().exec(\"calc\")}", new TemplateParserContext());
expression.getValue(standardEvaluationContext);
}
}
|