- 1. 简介
- 2. 开始
- 3. 配置
- 4. Flowable API
- 5. 集成 Spring
- 6. 部署
- 7. BPMN 2.0 介绍
- 8. BPMN 2.0 结构
- 9. 表单
- 10. JPA
- 11. 历史
- 12. 身份管理
- 13. Eclipse Designer
- 14. Flowable UI 应用
- 15. REST API
- 16. 集成 CDI
- 17. 集成 LDAP
- 18. 高级
- 19. 工具
18.12. 安全脚本
默认情况下,使用脚本任务时,执行的脚本与Java代码具有相似的能力。可以完全访问JVM,永远运行(无限循环),或占用大量内存。
相较而言,Java代码需要放在classpath的jar中,与流程定义的生命周期不一样。最终用户一般不会撰写Java代码,这基本上是开发者的工作。
而脚本是流程定义的一部分,生命周期一致。脚本任务不需要额外的jar部署步骤,而是在流程部署后就可以执行。有时,脚本任务中的脚本不是由开发者撰写的。所以会产生这个问题:脚本可以完全访问JVM,也可以在执行脚本时阻塞许多系统资源。因此允许执行来自任何人的脚本并不是一个好主意。
可以启用安全脚本功能解决这个问题。目前,这个功能只实现了javascript脚本,在项目中添加flowable-secure-javascript依赖启用。Maven:
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-secure-javascript</artifactId>
<version>${flowable.version}</version>
</dependency>
添加这个依赖会同时引入Rhino依赖(参见https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino)。Rhino是一个用于JDK的javascript引擎。过去包含在JDK6与7中,并已被Nashorn引擎取代。然而,Rhino项目仍然在继续开发。许多(包括Flowable用于实现安全脚本的)功能都在之后才加入。在撰写本手册的时候,Nashorn还没有实现安全脚本功能需要的功能。
这意味着脚本可能存在一些(基本很少)区别(例如,Rhino使用importPackage,而Nashorn使用load())。
通过专门的Configurator对象配置安全脚本,并在流程引擎实例化之前将其传递给流程引擎配置:
SecureJavascriptConfigurator configurator = new SecureJavascriptConfigurator()
.setWhiteListedClasses(new HashSet<String>(Arrays.asList("java.util.ArrayList")))
.setMaxStackDepth(10)
.setMaxScriptExecutionTime(3000L)
.setMaxMemoryUsed(3145728L)
.setNrOfInstructionsBeforeStateCheckCallback(10);
processEngineConfig.addConfigurator(configurator);
可以使用下列设置:
enableClassWhiteListing: 为true时,会将所有类加入黑名单。需要在白名单中添加希望运行的所有类,严格控制暴露给脚本的东西。默认为false。
whiteListedClasses: 一个全限定类名字符串的集合,表示允许在脚本中使用的类。例如,要在脚本中使用execution对象,需要在这个集合中添加org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl字符串。默认为空。
maxStackDepth: 限制在脚本中调用函数时的最大栈深度。可以用于避免在脚本中递归调用方法而导致的栈溢出异常。默认为-1(禁用)。
maxScriptExecutionTime: 脚本允许运行的最大时间。默认为-1(禁用)。
maxMemoryUsed: 脚本允许使用的最大内存数量,以字节计。请注意脚本引擎自己也要需要一定量的内存,也会算在这里。默认为-1(禁用)。
nrOfInstructionsBeforeStateCheckCallback: 脚本每执行x个指令,就通过回调函数进行一次脚本执行时间与内存检测。请注意这不是指脚本指令,而是指java字节码指令(一行脚本可能有上百行字节码指令)。默认为100。
请注意:maxMemoryUsed设置只能用于支持com.sun.management.ThreadMXBean#getThreadAllocatedBytes()方法的JVM,如Oracle JDK。
ScriptExecutionListener与ScriptTaskListener也有安全形式:org.flowable.scripting.secure.listener.SecureJavascriptExecutionListener与org.flowable.scripting.secure.listener.SecureJavascriptTaskListener。
像这样使用:
<flowable:executionListener event="start" class="org.flowable.scripting.secure.listener.SecureJavascriptExecutionListener">
<flowable:field name="script">
<flowable:string>
<![CDATA[
execution.setVariable('test');
]]>
</flowable:string>
</flowable:field>
<flowable:field name="language" stringValue="javascript" />
</flowable:executionListener>
可以通过GitHub上的单元测试, 查看不安全脚本以及通过安全脚本功能将其变得安全的例子,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论