1、导入依赖
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>1.8.6</version>
<scope>compile</scope>
</dependency>
2、demo.groovy脚本文件
class JsonParser {
/**
* return Map<String, Object> 请求头
*/
Map<String, Object> constructHeader() {
Map<String, Object> header = new HashMap<>();
//TODO 在这里处理header
header.put("Content-type", "application/json");
header.put("Authorization", "eyJ6aXAiOiJHWkl");
return header;
}
}
3、调用groovy文件
public Map<String, Object> constructHeader(String filePath) {
final CompilerConfiguration config = new CompilerConfiguration();// 自定义CompilerConfiguration,设置AST
config.setSourceEncoding("UTF-8");
// 设置该GroovyClassLoader的父ClassLoader为当前线程的加载器(默认)
GroovyClassLoader groovyClassLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
Map<String, Object> result = null;
File groovyFile = new File(filePath);
if (!groovyFile.exists()) {
return result;
}
try {
// 获得加载后的class
Class<?> groovyClass = groovyClassLoader.parseClass(groovyFile);
// 获得GroovyShell_2的实例
GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
// 反射调用方法得到返回值
result = (Map<String,Object>)groovyObject.invokeMethod("constructHeader",null);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
4、安全策略
public void initGroovyClassLoader() {
final SecureASTCustomizer secure = new SecureASTCustomizer();// 创建SecureASTCustomizer
secure.addExpressionCheckers(new NoSupportMethodsChecker());//静态内部类见下面
secure.setClosuresAllowed(true);// 禁止使用闭包
List<Integer> tokensBlacklist = new ArrayList<>();
tokensBlacklist.add(Types.KEYWORD_WHILE);// 添加关键字黑名单 while和goto
tokensBlacklist.add(Types.KEYWORD_GOTO);
secure.setTokensBlacklist(tokensBlacklist);
secure.setIndirectImportCheckEnabled(true);// 设置直接导入检查
List<String> importsWhiteList = new ArrayList<>();// 添加导入白名单
importsWhiteList.add("com.alibaba.fastjson.JSONObject");
importsWhiteList.add("groovy.json.JsonSlurper");
importsWhiteList.add("java.nio.charset.StandardCharsets");
importsWhiteList.add("com.tj.utils.JsonParser");
importsWhiteList.add("java.util.HashMap");
importsWhiteList.add("java.util.Map");
importsWhiteList.add("java.util.ArrayList");
importsWhiteList.add("java.util.List");
importsWhiteList.add("java.lang.String");
importsWhiteList.add("java.io.UnsupportedEncodingException");
importsWhiteList.add("java.lang.Object");
importsWhiteList.add("java.net.URLEncoder");
secure.setImportsWhitelist(importsWhiteList);
List<Class<? extends Statement>> statementBlacklist = new ArrayList<>();// statement 黑名单,不能使用while循环块
statementBlacklist.add(WhileStatement.class);
statementBlacklist.add(ForStatement.class);
statementBlacklist.add(DoWhileStatement.class);
statementBlacklist.add(WhileStatement.class);
statementBlacklist.add(AssertStatement.class);
secure.setStatementsBlacklist(statementBlacklist);
final CompilerConfiguration config = new CompilerConfiguration();// 自定义CompilerConfiguration,设置AST
config.addCompilationCustomizers(secure);
config.setSourceEncoding("UTF-8");
// 设置该GroovyClassLoader的父ClassLoader为当前线程的加载器(默认)
GroovyClassLoader groovyClassLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
}
static class NoSupportMethodsChecker implements SecureASTCustomizer.ExpressionChecker {
//方法黑名单
private final List<String> methodBlacklist = Arrays.asList("getClass", "class", "wait", "notify",
"notifyAll", "invokeMethod", "finalize", "execute","exec");
@Override
public boolean isAuthorized(Expression expression) {
if (expression instanceof MethodCallExpression) {
MethodCallExpression mc = (MethodCallExpression) expression;
String method = mc.getMethodAsString();
// String className = mc.getReceiver().getText();
if(methodBlacklist.contains(method)){
return false;
}
}
return true;
}
}