多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 2.10 自定义安全管理器 所有模板的本地调用都需要通过安全管理器校验,默认需要实现NativeSecurityManager 的public boolean permit(String resourceId, Class c, Object target, String method) 方法 如下是Beetl3.17版本后默认的白名单管理器,只允许java.util包的Java调用 ```java public class WhiteListNativeSecurityManager implements NativeSecurityManager { Pattern callPattern = null; public WhiteListNativeSecurityManager(){ allow(Arrays.asList("java.util")); } @Override public boolean permit(Object resourceId, Class c, Object target, String method) { if (c.isArray()) { // 允许调用,但实际上会在在其后调用中报错。不归此处管理 return true; } String name = c.getName(); int i = name.lastIndexOf('.'); if (i == -1) { // 无包名,肯定安全,允许调用 return true; } return callPattern.matcher(name).matches(); } } ``` 可以自定义安全管理器,或者调用allow方法添加更多允许的Java调用 ``` WhiteListNativeSecurityManager securityManager = new WhiteListNativeSecurityManager(); securityManager.allow(Arrays.asList("java.util","com.mycorp.project.util","com.mycorp.project.constants.Constants)); ``` 在Beetl3.17版本之前,默认使用的是DefaultNativeSecurityManager,他采用黑名单管理方式,杜绝了目前已知的漏洞(但不保证未来有安全漏洞)如下是默认管理器的实现方法 ```java public class DefaultNativeSecurityManager implements NativeSecurityManager{ @Override public boolean permit(String resourceId, Class c, Object target, String method){ if (c.isArray()){ //允许调用,但实际上会在在其后调用中报错。不归此处管理 return true; } String name = c.getSimpleName(); String pkg = c.getPackage().getName(); if (pkg.startsWith("java.lang")){ if (name.equals("Runtime") || name.equals("Process") || name.equals("ProcessBuilder") || name.equals("System")){ return false; } } //省略其他安全漏洞屏蔽代码 return true; } } ``` **需要强调的是,当允许在Beetl模板中使用Java本地调用,且使用DefaultNativeSecurityManager,且Beetl的模板编写权利交给浏览器终端用户,才有可能发生安全漏洞**,这跟Struts框架,Spring框架,JSON工具的漏洞原因是一样的,但发生几率相比这些Web框架来说,几乎不可能,就好比如果把Java编写编译的权利交给浏览器终端用户,那Java也有安全漏洞