我们现在可以使用Activiti7流程引擎运行时库运行应用程序,因此我们可以创建一些标准的Spring MVC rest调用来与流程引擎和可用的流程定义进行交互。
添加一些用户和组并启用Web安全性
为了能够与Process Runtime API进行交互,我们需要使用具有 ROLE_ACTIVITI_USER 角色的用户进行身份验证。如果我们只是直接从Java代码调用Process Runtime API,例如来自带有 main 方法 的类,那么我们可以在进行API调用之前直接设置用户上下文。请看这里 的例子。 注意。这样做只是为了玩API而不是真正的生产实现......
我们将创建自己的小ReST API,因此我们希望使用Basic Auth通过Web浏览器进行身份验证。Activiti使用Spring Security,因此我们可以很容易地做到这一点。
在src/main/java/org/activiti/training/activiti7apibasicprocessusertaskservicetaskevents
包中创建一个名为Activiti7ApplicationConfiguration
的Spring配置类 :
package org.activiti.training.activiti7apibasicprocessusertaskservicetaskevents;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
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;
/**
* Set up some users and groups that we can use when interacting with the process engine API.
* We use the testuser in the process definition so we need to include this user.
*
* We also enable Web security so we can build a simple ReST API that uses the Process Engine Java API. We need
* to be authenticated with a user that has the role ROLE_ACTIVITI_USER to be able to use the API.
*/
@Configuration
@EnableWebSecurity
public class Activiti7ApplicationConfiguration extends WebSecurityConfigurerAdapter {
private Logger logger = LoggerFactory.getLogger(Activiti7ApplicationConfiguration.class);
@Override
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService());
}
@Bean
public UserDetailsService myUserDetailsService() {
InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
String[][] usersGroupsAndRoles = {
{"mbergljung", "1234", "ROLE_ACTIVITI_USER", "GROUP_activitiTraining"},
{"testuser", "1234", "ROLE_ACTIVITI_USER", "GROUP_activitiTraining"},
{"system", "1234", "ROLE_ACTIVITI_USER"},
{"admin", "1234", "ROLE_ACTIVITI_ADMIN"},
};
for (String[] user : usersGroupsAndRoles) {
List<String> authoritiesStrings = Arrays.asList(Arrays.copyOfRange(user, 2, user.length));
logger.info("> Registering new user: " + user[0] + " with the following Authorities[" + authoritiesStrings + "]");
inMemoryUserDetailsManager.createUser(new User(user[0], passwordEncoder().encode(user[1]),
authoritiesStrings.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList())));
}
return inMemoryUserDetailsManager;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
设置我们在与流程引擎API交互时可以使用的一些用户和组。我们 在流程定义中使用testuser (分配给用户任务1),因此我们需要包含此用户。我们还启用了Web安全性,因此我们可以构建一个使用Process Engine Java API的简单ReST API。
添加ReST调用以列出流程定义
首先,让我们添加一个列出已部署流程定义的ReST调用。 在org/activiti/training/activiti7apibasicprocessusertaskservicetaskevents
包中创建一个名为rest 的新子包。然后在这个新包中添加一个名为ProcessDefinitionsController
的新Spring MVC控制器,如下所示:
package org.activiti.training.activiti7apibasicprocessusertaskservicetaskevents.rest;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* ReST controller to interact with deployed process definitions
*
*/
@RestController
public class ProcessDefinitionsController {
private Logger logger = LoggerFactory.getLogger(ProcessDefinitionsController.class);
@Autowired
private ProcessRuntime processRuntime;
@GetMapping("/process-definitions")
public List<ProcessDefinition> getProcessDefinitions() {
Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
logger.info("> Available Process definitions: " + processDefinitionPage.getTotalItems());
for (ProcessDefinition pd : processDefinitionPage.getContent()) {
logger.info("\t > Process definition: " + pd);
}
return processDefinitionPage.getContent();
}
}
首先注入 ProcessRuntime Spring bean
,以便我们可以使用Process Runtime API
,它具有以下方法:
public interface ProcessRuntime {
ProcessRuntimeConfiguration configuration();
ProcessDefinition processDefinition(String var1);
Page<ProcessDefinition> processDefinitions(Pageable var1);
Page<ProcessDefinition> processDefinitions(Pageable var1, GetProcessDefinitionsPayload var2);
ProcessInstance start(StartProcessPayload var1);
Page<ProcessInstance> processInstances(Pageable var1);
Page<ProcessInstance> processInstances(Pageable var1, GetProcessInstancesPayload var2);
ProcessInstance processInstance(String var1);
ProcessInstance suspend(SuspendProcessPayload var1);
ProcessInstance resume(ResumeProcessPayload var1);
ProcessInstance delete(DeleteProcessPayload var1);
void signal(SignalPayload var1);
ProcessDefinitionMeta processDefinitionMeta(String var1);
ProcessInstanceMeta processInstanceMeta(String var1);
List<VariableInstance> variables(GetVariablesPayload var1);
void removeVariables(RemoveProcessVariablesPayload var1);
void setVariables(SetProcessVariablesPayload var1);
}
在这种情况下,我们只需要 processDefinitions() 方法。该 /过程定义 URL路径用于该休息GET调用。
现在,按照前面的描述打包并运行应用程序。启动应用程序时,您应该看到指示所有内容都已正确实现的日志:
...
2018-08-28 15:12:49.742 INFO 21982 --- [ost-startStop-1] .a.t.a.Activiti7ApplicationConfiguration : > Registering new user: mbergljung with the following Authorities[[ROLE_ACTIVITI_USER, GROUP_activitiTraining]]
2018-08-28 15:12:49.869 INFO 21982 --- [ost-startStop-1] .a.t.a.Activiti7ApplicationConfiguration : > Registering new user: testuser with the following Authorities[[ROLE_ACTIVITI_USER, GROUP_activitiTraining]]
2018-08-28 15:12:49.994 INFO 21982 --- [ost-startStop-1] .a.t.a.Activiti7ApplicationConfiguration : > Registering new user: system with the following Authorities[[ROLE_ACTIVITI_USER]]
2018-08-28 15:12:50.113 INFO 21982 --- [ost-startStop-1] .a.t.a.Activiti7ApplicationConfiguration : > Registering new user: admin with the following Authorities[[ROLE_ACTIVITI_ADMIN]]
…
org.springframework.security.web.authentication.www.BasicAuthenticationFilter@6fdbe764,
...
2018-08-28 15:12:53.119 INFO 21982 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/process-definitions],methods=[GET]}" onto public java.util.List<org.activiti.api.process.model.ProcessDefinition> org.activiti.training.activiti7apibasicprocessusertaskservicetaskevents.rest.ProcessDefinitionsController.getProcessDefinitions()
...
转到浏览器并点击 http://localhost:8080/process-definitions,您将看到一个登录对话框。输入具有 ROLE_ACTIVITI_USER 角色的用户的用户名和密码,例如 testuser/1234。然后你应该得到一个像这样的响应:
[
{
id: "c68315b2-fa2a-11e8-9c34-acde48001122",
name: "Sample Process",
version: 1,
key: "sampleproc-e9b76ff9-6f70-42c9-8dee-f6116c533a6d"
}
]
在控制台日志中,您应该看到以下内容:
2018-08-28 15:13:09.678 INFO 21982 --- [nio-8080-exec-1] o.a.t.a.r.ProcessDefinitionsController : > Available Process definitions: 1
2018-08-28 15:13:09.678 INFO 21982 --- [nio-8080-exec-1] o.a.t.a.r.ProcessDefinitionsController : > Process definition: ProcessDefinition{id='c68315b2-fa2a-11e8-9c34-acde48001122', name='Sample Process', key='sampleproc-e9b76ff9-6f70-42c9-8dee-f6116c533a6d', description='null', formKey='null', version=1}
我想问个问题,Activiti7是基于Spring Cloud Gateway的,而Spring Cloud Gateway是基于WebFlux的,你这样使用@EnableWebSecurity来配置Spring Security,将来整个项目完全整合到一起后不会冲突么?(Spring Cloud Gateway与Spring Security整合必须、只能使用@EnableWebFluxSecurity)。
你这个加了验证 之前的druid 和 swagger 都用不了怎么解决啊
可以用
如何将其封装成restful接口对外提供服务?
看这篇文章:https://www.xugj520.cn/archives/activiti_swagger_druid.html
系列文章:https://www.xugj520.cn/category/Activiti/