@@ -50,6 +50,12 @@ | |||
<groupId>mysql</groupId> | |||
<artifactId>mysql-connector-java</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<optional>true</optional> | |||
</dependency> | |||
</dependencies> | |||
<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; | |||
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.runner.RunWith; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.boot.test.context.SpringBootTest; | |||
import org.springframework.test.context.junit4.SpringRunner; | |||
@@ -9,8 +15,16 @@ import org.springframework.test.context.junit4.SpringRunner; | |||
@SpringBootTest | |||
public class SpringBootDemoActivitiApplicationTests { | |||
@Autowired | |||
private ProcessRuntime processRuntime; | |||
@Autowired | |||
private SecurityUtil securityUtil; | |||
@Test | |||
public void contextLoads() { | |||
securityUtil.logInAs("salaboy"); | |||
Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10)); | |||
processDefinitionPage.getContent().forEach(System.out::println); | |||
} | |||
} | |||