| @@ -50,6 +50,12 @@ | |||||
| <groupId>mysql</groupId> | <groupId>mysql</groupId> | ||||
| <artifactId>mysql-connector-java</artifactId> | <artifactId>mysql-connector-java</artifactId> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>org.projectlombok</groupId> | |||||
| <artifactId>lombok</artifactId> | |||||
| <optional>true</optional> | |||||
| </dependency> | |||||
| </dependencies> | </dependencies> | ||||
| <build> | <build> | ||||
| @@ -0,0 +1,64 @@ | |||||
| package com.xkcoding.activiti.config; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| import org.springframework.context.annotation.Bean; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; | |||||
| import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | |||||
| import org.springframework.security.core.authority.SimpleGrantedAuthority; | |||||
| import org.springframework.security.core.userdetails.User; | |||||
| import org.springframework.security.core.userdetails.UserDetailsService; | |||||
| import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | |||||
| import org.springframework.security.crypto.password.PasswordEncoder; | |||||
| import org.springframework.security.provisioning.InMemoryUserDetailsManager; | |||||
| import java.util.Arrays; | |||||
| import java.util.List; | |||||
| import java.util.stream.Collectors; | |||||
| /** | |||||
| * <p> | |||||
| * 安全配置类 | |||||
| * </p> | |||||
| * | |||||
| * @package: com.xkcoding.activiti.config | |||||
| * @description: 安全配置类 | |||||
| * @author: yangkai.shen | |||||
| * @date: Created in 2019-07-01 18:40 | |||||
| * @copyright: Copyright (c) 2019 | |||||
| * @version: V1.0 | |||||
| * @modified: yangkai.shen | |||||
| */ | |||||
| @Slf4j | |||||
| @Configuration | |||||
| public class SecurityConfiguration extends WebSecurityConfigurerAdapter { | |||||
| @Override | |||||
| protected void configure(AuthenticationManagerBuilder auth) throws Exception { | |||||
| auth.userDetailsService(userDetailsService()); | |||||
| } | |||||
| @Bean | |||||
| protected UserDetailsService myUserDetailsService() { | |||||
| InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager(); | |||||
| String[][] usersGroupsAndRoles = {{"salaboy", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"}, {"ryandawsonuk", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"}, {"erdemedeiros", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"}, {"other", "password", "ROLE_ACTIVITI_USER", "GROUP_otherTeam"}, {"admin", "password", "ROLE_ACTIVITI_ADMIN"}}; | |||||
| for (String[] user : usersGroupsAndRoles) { | |||||
| List<String> authoritiesStrings = Arrays.asList(Arrays.copyOfRange(user, 2, user.length)); | |||||
| log.info("> Registering new user: " + user[0] + " with the following Authorities[" + authoritiesStrings + "]"); | |||||
| inMemoryUserDetailsManager.createUser(new User(user[0], passwordEncoder().encode(user[1]), authoritiesStrings | |||||
| .stream() | |||||
| .map(SimpleGrantedAuthority::new) | |||||
| .collect(Collectors.toList()))); | |||||
| } | |||||
| return inMemoryUserDetailsManager; | |||||
| } | |||||
| @Bean | |||||
| public PasswordEncoder passwordEncoder() { | |||||
| return new BCryptPasswordEncoder(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,79 @@ | |||||
| package com.xkcoding.activiti.util; | |||||
| import lombok.RequiredArgsConstructor; | |||||
| 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.security.core.userdetails.UserDetailsService; | |||||
| import org.springframework.stereotype.Component; | |||||
| import java.util.Collection; | |||||
| /** | |||||
| * <p> | |||||
| * 认证工具 | |||||
| * </p> | |||||
| * | |||||
| * @package: com.xkcoding.activiti.util | |||||
| * @description: 认证工具 | |||||
| * @author: yangkai.shen | |||||
| * @date: Created in 2019-07-01 18:38 | |||||
| * @copyright: Copyright (c) 2019 | |||||
| * @version: V1.0 | |||||
| * @modified: yangkai.shen | |||||
| */ | |||||
| @Component | |||||
| @RequiredArgsConstructor(onConstructor_ = @Autowired) | |||||
| public class SecurityUtil { | |||||
| private final UserDetailsService 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"); | |||||
| } | |||||
| SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() { | |||||
| @Override | |||||
| public Collection<? extends GrantedAuthority> getAuthorities() { | |||||
| 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 isAuthenticated) throws IllegalArgumentException { | |||||
| } | |||||
| @Override | |||||
| public String getName() { | |||||
| return user.getUsername(); | |||||
| } | |||||
| })); | |||||
| org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,78 @@ | |||||
| <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |||||
| <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:yaoqiang="http://bpmn.sourceforge.net" exporter="Yaoqiang BPMN Editor" exporterVersion="5.3" expressionLanguage="http://www.w3.org/1999/XPath" id="m1544167269809" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://bpmn.sourceforge.net/schemas/BPMN20.xsd"> | |||||
| <process id="myProcess_1" isClosed="false" isExecutable="true" processType="None"> | |||||
| <extensionElements> | |||||
| <yaoqiang:description/> | |||||
| <yaoqiang:pageFormat height="841.8897637795276" imageableHeight="831.8897637795276" imageableWidth="588.1102362204724" imageableX="5.0" imageableY="5.0" orientation="0" width="598.1102362204724"/> | |||||
| <yaoqiang:page background="#FFFFFF" horizontalCount="1" verticalCount="1"/> | |||||
| </extensionElements> | |||||
| <startEvent id="_2" isInterrupting="true" name="StartEvent" parallelMultiple="false"> | |||||
| <outgoing>_6</outgoing> | |||||
| <outputSet/> | |||||
| </startEvent> | |||||
| <userTask activiti:candidateGroups="activitiTeam" activiti:exclusive="true" completionQuantity="1" id="_3" implementation="##unspecified" isForCompensation="false" name="first" startQuantity="1"> | |||||
| <incoming>_6</incoming> | |||||
| <outgoing>_7</outgoing> | |||||
| </userTask> | |||||
| <userTask activiti:candidateGroups="activitiTeam" activiti:exclusive="true" completionQuantity="1" id="_4" implementation="##unspecified" isForCompensation="false" name="second" startQuantity="1"> | |||||
| <incoming>_7</incoming> | |||||
| <outgoing>_8</outgoing> | |||||
| </userTask> | |||||
| <endEvent id="_5" name="EndEvent"> | |||||
| <incoming>_8</incoming> | |||||
| <inputSet/> | |||||
| </endEvent> | |||||
| <sequenceFlow id="_6" sourceRef="_2" targetRef="_3"/> | |||||
| <sequenceFlow id="_7" sourceRef="_3" targetRef="_4"/> | |||||
| <sequenceFlow id="_8" sourceRef="_4" targetRef="_5"/> | |||||
| </process> | |||||
| <bpmndi:BPMNDiagram id="Yaoqiang_Diagram-myProcess_1" name="New Diagram" resolution="96.0"> | |||||
| <bpmndi:BPMNPlane bpmnElement="myProcess_1"> | |||||
| <bpmndi:BPMNShape bpmnElement="_2" id="Yaoqiang-_2"> | |||||
| <omgdc:Bounds height="32.0" width="32.0" x="65.0" y="80.0"/> | |||||
| <bpmndi:BPMNLabel> | |||||
| <omgdc:Bounds height="18.96" width="60.0" x="51.0" y="120.52"/> | |||||
| </bpmndi:BPMNLabel> | |||||
| </bpmndi:BPMNShape> | |||||
| <bpmndi:BPMNShape bpmnElement="_3" id="Yaoqiang-_3"> | |||||
| <omgdc:Bounds height="55.0" width="85.0" x="170.0" y="115.0"/> | |||||
| <bpmndi:BPMNLabel> | |||||
| <omgdc:Bounds height="18.96" width="28.0" x="198.5" y="135.02"/> | |||||
| </bpmndi:BPMNLabel> | |||||
| </bpmndi:BPMNShape> | |||||
| <bpmndi:BPMNShape bpmnElement="_4" id="Yaoqiang-_4"> | |||||
| <omgdc:Bounds height="55.0" width="85.0" x="310.0" y="155.0"/> | |||||
| <bpmndi:BPMNLabel> | |||||
| <omgdc:Bounds height="18.96" width="45.0" x="330.0" y="175.02"/> | |||||
| </bpmndi:BPMNLabel> | |||||
| </bpmndi:BPMNShape> | |||||
| <bpmndi:BPMNShape bpmnElement="_5" id="Yaoqiang-_5"> | |||||
| <omgdc:Bounds height="32.0" width="32.0" x="505.0" y="220.0"/> | |||||
| <bpmndi:BPMNLabel> | |||||
| <omgdc:Bounds height="18.96" width="55.0" x="493.5" y="260.52"/> | |||||
| </bpmndi:BPMNLabel> | |||||
| </bpmndi:BPMNShape> | |||||
| <bpmndi:BPMNEdge bpmnElement="_8" id="Yaoqiang-_8"> | |||||
| <omgdi:waypoint x="395.0" y="182.5"/> | |||||
| <omgdi:waypoint x="505.0" y="236.0"/> | |||||
| <bpmndi:BPMNLabel> | |||||
| <omgdc:Bounds height="18.96" width="6.0" x="447.0" y="199.77"/> | |||||
| </bpmndi:BPMNLabel> | |||||
| </bpmndi:BPMNEdge> | |||||
| <bpmndi:BPMNEdge bpmnElement="_7" id="Yaoqiang-_7"> | |||||
| <omgdi:waypoint x="255.0" y="142.5"/> | |||||
| <omgdi:waypoint x="310.0" y="182.5"/> | |||||
| <bpmndi:BPMNLabel> | |||||
| <omgdc:Bounds height="18.96" width="6.0" x="279.5" y="153.02"/> | |||||
| </bpmndi:BPMNLabel> | |||||
| </bpmndi:BPMNEdge> | |||||
| <bpmndi:BPMNEdge bpmnElement="_6" id="Yaoqiang-_6"> | |||||
| <omgdi:waypoint x="97.0" y="96.0"/> | |||||
| <omgdi:waypoint x="170.0" y="142.5"/> | |||||
| <bpmndi:BPMNLabel> | |||||
| <omgdc:Bounds height="18.96" width="6.0" x="130.5" y="109.77"/> | |||||
| </bpmndi:BPMNLabel> | |||||
| </bpmndi:BPMNEdge> | |||||
| </bpmndi:BPMNPlane> | |||||
| </bpmndi:BPMNDiagram> | |||||
| </definitions> | |||||
| @@ -1,7 +1,13 @@ | |||||
| package com.xkcoding.activiti; | package com.xkcoding.activiti; | ||||
| import com.xkcoding.activiti.util.SecurityUtil; | |||||
| import org.activiti.api.process.model.ProcessDefinition; | |||||
| import org.activiti.api.process.runtime.ProcessRuntime; | |||||
| import org.activiti.api.runtime.shared.query.Page; | |||||
| import org.activiti.api.runtime.shared.query.Pageable; | |||||
| import org.junit.Test; | import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.boot.test.context.SpringBootTest; | import org.springframework.boot.test.context.SpringBootTest; | ||||
| import org.springframework.test.context.junit4.SpringRunner; | import org.springframework.test.context.junit4.SpringRunner; | ||||
| @@ -9,8 +15,16 @@ import org.springframework.test.context.junit4.SpringRunner; | |||||
| @SpringBootTest | @SpringBootTest | ||||
| public class SpringBootDemoActivitiApplicationTests { | public class SpringBootDemoActivitiApplicationTests { | ||||
| @Autowired | |||||
| private ProcessRuntime processRuntime; | |||||
| @Autowired | |||||
| private SecurityUtil securityUtil; | |||||
| @Test | @Test | ||||
| public void contextLoads() { | public void contextLoads() { | ||||
| securityUtil.logInAs("salaboy"); | |||||
| Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10)); | |||||
| processDefinitionPage.getContent().forEach(System.out::println); | |||||
| } | } | ||||
| } | } | ||||