如何限制仅候选用户/组可完成Camunda任务?
Camunda任务权限控制问题:阻止非授权用户完成任务
我有一个集成Camunda的Spring Boot应用,尝试通过该应用管理Camunda任务与流程执行,但无法阻止任意用户通过TaskService完成任务。
以「请假申请」流程为例:
- 员工发起流程
- 经理审批申请 >> 候选用户=经理
- 向员工发送通知
我通过Camunda任务服务处理流程执行,代码如下:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); TaskService taskService = processEngine.getTaskService(); Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); taskService.complete(task.getId(), taskVariables);
目前问题是任意用户调用taskService.complete方法都能完成任务,请问如何确保Camunda不允许「Employee1」这类用户完成审批任务?
解决方案
要实现Camunda的任务权限控制,核心是利用Camunda的任务分配与权限校验机制,确保只有授权用户(比如经理)才能完成对应任务,以下是具体实现方式:
1. 启用Camunda身份认证与授权
Camunda默认关闭权限校验,需先在配置文件中开启:
camunda.bpm.authorization.enabled: true camunda.bpm.id.enabled: true
开启后,Camunda会基于内置身份系统(或你集成的外部身份系统)校验用户对任务的操作权限。
2. 流程设计阶段明确任务候选用户/组
确保「经理审批」任务已正确配置候选用户(如指定manager角色或具体经理用户ID),这是权限校验的基础。在BPMN文件中配置:
<userTask id="approveLeave" name="经理审批申请"> <potentialOwner> <resourceAssignmentExpression> <formalExpression>manager</formalExpression> <!-- 支持用户ID、组ID或动态表达式 --> </resourceAssignmentExpression> </potentialOwner> </userTask>
3. 代码中添加权限校验逻辑
调用complete方法前,先校验当前用户是否有权限操作该任务:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); TaskService taskService = processEngine.getTaskService(); IdentityService identityService = processEngine.getIdentityService(); // 从请求上下文获取当前用户ID,比如"Employee1"或"Manager1" String currentUserId = "Employee1"; // 设置当前操作的用户,Camunda会基于该用户做权限校验 identityService.setAuthenticatedUserId(currentUserId); try { // 只查询当前用户有权限处理的任务 Task task = taskService.createTaskQuery() .processInstanceId(processInstanceId) .taskCandidateUser(currentUserId) .singleResult(); if (task == null) { throw new SecurityException("当前用户无权限操作该任务"); } taskService.complete(task.getId(), taskVariables); } finally { // 清理认证上下文,避免影响后续操作 identityService.clearAuthentication(); }
关键要点:
- 通过
identityService.setAuthenticatedUserId绑定当前操作用户,Camunda内部会自动校验权限 - 查询任务时用
taskCandidateUser(currentUserId)过滤,避免查询到无权限的任务
4. 自定义权限拦截器(可选)
如果需要统一的权限校验逻辑,可以自定义拦截器:
@Component public class TaskPermissionInterceptor { private final TaskService taskService; private final IdentityService identityService; public TaskPermissionInterceptor(TaskService taskService, IdentityService identityService) { this.taskService = taskService; this.identityService = identityService; } public void checkTaskPermission(String taskId) { String currentUserId = identityService.getCurrentAuthentication().getUserId(); boolean hasPermission = taskService.createTaskQuery() .taskId(taskId) .taskCandidateUser(currentUserId) .count() > 0; if (!hasPermission) { throw new SecurityException("用户" + currentUserId + "无权限完成任务" + taskId); } } }
业务代码中调用拦截器:
taskPermissionInterceptor.checkTaskPermission(task.getId()); taskService.complete(task.getId(), taskVariables);
5. REST API权限控制(若适用)
如果通过Camunda REST API操作任务,确保REST API启用权限校验,外部调用者需携带合法用户身份信息,Camunda会自动完成权限校验。
内容的提问来源于stack exchange,提问作者Mike Mouannes
相关产品推荐
相关产品推荐

