解决springboot集成activiti7工作流权限认证问题

springboot集成activiti7工作流权限认证问题

如果你的登录不是用的security方式, 集成后会有权限认证的问题,因为activiti7自带spring-security

代码
1、重写security 的UserDetailsService方法

package com.xxx.activiti.config;

import com.xxx.common.core.constant.SecurityConstants;
import com.xxx.system.api.model.LoginUser;
import com.xxx.system.api.system.RemoteUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private RemoteUserService remoteUserService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LoginUser user = remoteUserService.getUserInfo(username, SecurityConstants.INNER).getData();
        return createLoginUser(user);
    }

    public UserDetails createLoginUser(LoginUser user) {
        Set<String> postCode = user.getPostCode();
        postCode = postCode.parallelStream().map( s ->  "GROUP_" + s).collect(Collectors.toSet());
        postCode.add("ROLE_ACTIVITI_USER");
        List<SimpleGrantedAuthority> collect = postCode.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList());
        return new User(user.getPermissions(), collect, user.getSysUser());
    }
}

2、给auth赋值

package com.xxx.activiti.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import javax.security.auth.Subject;
import java.util.Collection;

@Component
public class SecurityActivitiUtil {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    public void logInAs(String username) {
        UserDetails user = userDetailsService.loadUserByUsername(username);
        if (user == null) {
            throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user");
        }

        Authentication authentication = new Authentication() {
            @Override
            public String getName() {
                return user.getUsername();
            }

            @Override
            public boolean implies(Subject subject) {
                return false;
            }

            @Override
            public Collection<? extends GrantedAuthority> getAuthorities() {
               // Set<String> postCode = user.getPostCode();
                //List<SimpleGrantedAuthority> collect = postCode.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList());
                return user.getAuthorities();
            }

            @Override
            public Object getCredentials() {
                return user.getPassword();
            }

            @Override
            public Object getDetails() {

                return user;
            }

            @Override
            public Object getPrincipal() {

                return user;
            }

            @Override
            public boolean isAuthenticated() {
                return true;
            }

            @Override
            public void setAuthenticated(boolean b) throws IllegalArgumentException {

            }
        };

        SecurityContextImpl securityContext = new SecurityContextImpl();
        securityContext.setAuthentication(authentication);
        SecurityContextHolder.setContext(securityContext);
        org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
    }
}

3、在每次调用工作流的方法前调用

 SysUser sysUser= SecurityUtils.getLoginUser().getSysUser();
        //activiti7 权限认证
        securityActivitiUtil.logInAs(sysUser.getUserName());

4、另外说一下 remoteUserService.getUserInfo大致内容:
主要是通过username获取用户信息,最重要的是包括roles集合:

/**
     * 获取当前用户信息
     */
    @InnerAuth
    @GetMapping("/info/{username}")
    public R<LoginUser> info(@PathVariable("username") String username)
    {
        SysUser sysUser = userService.selectUserByUserName(username);
        if (StringUtils.isNull(sysUser))
        {
            return R.fail("用户名或密码错误");
        }
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(sysUser.getUserId());
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(sysUser.getUserId());
        Set<String> postCode = postService.selectPostCodeByUserId(sysUser.getUserId());
        postCode = postCode.parallelStream().map( s ->  "GROUP_" + s).collect(Collectors.toSet());
        LoginUser sysUserVo = new LoginUser();
        sysUserVo.setSysUser(sysUser);
        sysUserVo.setRoles(roles);
        sysUserVo.setPermissions(permissions);
        sysUserVo.setPostCode(postCode);
        return R.ok(sysUserVo);
    }

如果有人用过security做登录权限验证,那么这个问题很简单

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的 Spring Boot 集成 Activiti 工作的示例代码: 1. 在 pom.xml 中添加依赖: ```xml <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter-basic</artifactId> <version>${activiti.version}</version> </dependency> ``` 2. 创建一个 Activiti 配置类: ```java @Configuration public class ActivitiConfig { @Bean public ProcessEngineConfiguration processEngineConfiguration(DataSource dataSource, PlatformTransactionManager transactionManager) { SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration(); configuration.setDataSource(dataSource); configuration.setTransactionManager(transactionManager); configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); configuration.setAsyncExecutorActivate(false); return configuration; } @Bean public ProcessEngineFactoryBean processEngineFactoryBean(ProcessEngineConfiguration processEngineConfiguration) { ProcessEngineFactoryBean factoryBean = new ProcessEngineFactoryBean(); factoryBean.setProcessEngineConfiguration(processEngineConfiguration); return factoryBean; } @Bean public RepositoryService repositoryService(ProcessEngine processEngine) { return processEngine.getRepositoryService(); } @Bean public RuntimeService runtimeService(ProcessEngine processEngine) { return processEngine.getRuntimeService(); } @Bean public TaskService taskService(ProcessEngine processEngine) { return processEngine.getTaskService(); } @Bean public HistoryService historyService(ProcessEngine processEngine) { return processEngine.getHistoryService(); } @Bean public ManagementService managementService(ProcessEngine processEngine) { return processEngine.getManagementService(); } @Bean public IdentityService identityService(ProcessEngine processEngine) { return processEngine.getIdentityService(); } @Bean public FormService formService(ProcessEngine processEngine) { return processEngine.getFormService(); } } ``` 3. 创建一个简单的工作程: ```xml <?xml version="1.0" encoding="UTF-8"?> <definitions id="definitions" targetNamespace="http://www.activiti.org/test" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"> <process id="testProcess" name="Test Process"> <startEvent id="start" name="Start"></startEvent> <userTask id="task1" name="Task 1" assignee="${user}"></userTask> <exclusiveGateway id="gateway1"></exclusiveGateway> <userTask id="task2" name="Task 2" assignee="${user}" /> <endEvent id="end" name="End"></endEvent> <sequenceFlow id="flow1" sourceRef="start" targetRef="task1"></sequenceFlow> <sequenceFlow id="flow2" sourceRef="task1" targetRef="gateway1"></sequenceFlow> <sequenceFlow id="flow3" sourceRef="gateway1" targetRef="task2"> <conditionExpression xsi:type="tFormalExpression">${approved == true}</conditionExpression> </sequenceFlow> <sequenceFlow id="flow4" sourceRef="gateway1" targetRef="end"> <conditionExpression xsi:type="tFormalExpression">${approved == false}</conditionExpression> </sequenceFlow> </process> </definitions> ``` 4. 创建一个处理器来启动和完成工作程: ```java @Service public class WorkflowService { private final TaskService taskService; private final RuntimeService runtimeService; @Autowired public WorkflowService(TaskService taskService, RuntimeService runtimeService) { this.taskService = taskService; this.runtimeService = runtimeService; } public void startWorkflow(String processDefinitionKey, Map<String, Object> variables) { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables); } public void completeTask(String taskId, Map<String, Object> variables) { taskService.complete(taskId, variables); } } ``` 5. 在控制器中使用处理器来启动和完成工作程: ```java @RestController @RequestMapping("/workflow") public class WorkflowController { private final WorkflowService workflowService; @Autowired public WorkflowController(WorkflowService workflowService) { this.workflowService = workflowService; } @PostMapping("/start") public void startWorkflow(@RequestParam String processDefinitionKey, @RequestParam String user) { Map<String, Object> variables = new HashMap<>(); variables.put("user", user); workflowService.startWorkflow(processDefinitionKey, variables); } @PostMapping("/complete") public void completeTask(@RequestParam String taskId, @RequestParam boolean approved) { Map<String, Object> variables = new HashMap<>(); variables.put("approved", approved); workflowService.completeTask(taskId, variables); } } ``` 上述代码中,我们创建了一个 Activiti 配置类来配置 Activiti 引擎,包括数据库配置、事务管理器等。我们还创建了一个简单的工作程,其中包括一个开始事件、两个用户任务、一个排他网关和一个结束事件。最后,我们创建了一个处理器来启动和完成工作程,并在控制器中使用处理器来处理具体的请求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值