Flowable 是可插拔的架构,支持多种引擎和功能插件
1.这里只使用flowable的流程引擎和在线工作流设计器:版本6.8.0
<!-- flowable -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-process-rest</artifactId>
</dependency>
<!-- modeler绘制流程图 -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter-ui-modeler</artifactId>
</dependency>
yml一般无需特别的配置,使用默认的配置即可。
2.设置modeler跳过它自带的security安全认证
在main中排除安全配置类
@SpringBootApplication(exclude = {FlowableUiSecurityAutoConfiguration.class})
并重写一个配置类:
/**
* @author programmer
* @version 1.0
* @create 2023/12/21 19:27
* @description 重写 FlowableUiSecurityAutoConfiguration 类实现无需认证即可使用在线流程图绘制
* @since 1.0
**/
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter({
IdmEngineServicesAutoConfiguration.class,
})
@AutoConfigureBefore({
FlowableSecurityAutoConfiguration.class,
OAuth2ClientAutoConfiguration.class,
})
public class FlowableUiSecurityConfig {
private static final Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry> DEFAULT_AUTHORIZE_REQUESTS = requests -> {
requests.antMatchers("/app/rest/account").permitAll()
.antMatchers("/app/rest/runtime/app-definitions").permitAll()
.antMatchers("/idm-app/rest/authenticate").permitAll()
.antMatchers("/idm-app/rest/account").permitAll()
.antMatchers("/app/rest/**", "/workflow/").permitAll()
.antMatchers("/admin-app/**", "/admin/").permitAll()
.antMatchers("/idm-app/**").permitAll()
.antMatchers("/modeler-app/**", "/modeler/").permitAll()
.antMatchers("/").permitAll()
.antMatchers("/app/authentication").permitAll()
.antMatchers("/idm").permitAll();
};
private static final Customizer<LogoutConfigurer<HttpSecurity>> DEFAULT_LOGOUT = logout -> {
logout.logoutUrl("/app/logout");
};
private static final Customizer<HeadersConfigurer<HttpSecurity>> DEFAULT_HEADERS = headers -> {
headers.frameOptions()
.sameOrigin()
.addHeaderWriter(new XXssProtectionHeaderWriter());
};
@Configuration(proxyBeanMethods = false)
//@ConditionalOnMissingClass("org.flowable.ui.idm.service.GroupServiceImpl")
public static class RemoteIdmConfiguration {
// This configuration is used when the idm application is not part of the UI application
@Bean
public RemoteIdmService remoteIdmService() {
FlowableCommonAppProperties properties = new FlowableCommonAppProperties();
properties.setIdmUrl("http://localhost");
properties.getIdmAdmin().setUser("admin");
properties.getIdmAdmin().setPassword("admin");
return new RemoteIdmServiceImpl(properties);
}
@Bean
public UserCache remoteIdmUserCache(FlowableCommonAppProperties properties, RemoteIdmService remoteIdmService) {
return new RemoteIdmUserCache(properties, remoteIdmService);
}
@Bean
@ConditionalOnMissingBean
public UserDetailsService flowableUiUserDetailsService(RemoteIdmService remoteIdmService) {
return new RemoteIdmUserDetailsService(remoteIdmService);
}
@Bean
@ConditionalOnMissingBean
public PersistentTokenService flowableUiPersistentTokenService(RemoteIdmService remoteIdmService) {
return new RemoteIdmPersistentTokenService(remoteIdmService);
}
@Bean
public RemoteIdmAuthenticationProvider remoteIdmAuthenticationProvider(RemoteIdmService remoteIdmService) {
return new RemoteIdmAuthenticationProvider(remoteIdmService);
}
}
@Configuration(proxyBeanMethods = false)
@Order(SecurityConstants.FORM_LOGIN_SECURITY_ORDER)
@ConditionalOnProperty(prefix = "flowable.common.app.security", name = "type", havingValue = "idm", matchIfMissing = true)
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Autowired
protected ObjectProvider<RememberMeServices> rememberMeServicesObjectProvider;
@Autowired
protected FlowableCommonAppProperties commonAppProperties;
@Override
protected void configure(HttpSecurity http) throws Exception {
RememberMeServices rememberMeServices = rememberMeServicesObjectProvider.getIfAvailable();
String key = null;
if (rememberMeServices instanceof AbstractRememberMeServices) {
key = ((AbstractRememberMeServices) rememberMeServices).getKey();
}
if (rememberMeServices != null) {
http.rememberMe()
.key(key)
.rememberMeServices(rememberMeServices);
}
http
.exceptionHandling()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.logout(logout -> {
DEFAULT_LOGOUT.customize(logout);
logout.logoutSuccessUrl("/");
logout.addLogoutHandler(new ClearFlowableCookieLogoutHandler());
})
.csrf()
.disable() // Disabled, cause enabling it will cause sessions
.headers(DEFAULT_HEADERS)
// Never persist the security context
.securityContext().securityContextRepository(new NullSecurityContextRepository())
.and()
.authorizeRequests(DEFAULT_AUTHORIZE_REQUESTS)
;
http.formLogin().disable();
//http.apply(new FlowableUiCustomFormLoginConfigurer<>());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String password = passwordEncoder.encode("admin");
auth.inMemoryAuthentication().withUser("admin").password(password).roles("admin");
}
@Bean
PasswordEncoder password() {
return new BCryptPasswordEncoder();
}
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "flowable.common.app.security", name = "type", havingValue = "idm", matchIfMissing = true)
public ApiHttpSecurityCustomizer defaultApiHttpSecurityCustomizer() {
return new DefaultApiHttpSecurityCustomizer();
}
}
再添加一个同包名和类名的获取用户信息类,覆盖flowable的
package org.flowable.ui.common.rest.idm.remote;
import org.flowable.ui.common.model.UserRepresentation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author programmer
* @version 1.0
* @create 2023/12/22 14:00
* @description 重写覆盖 flowable-ui-common-rest中的RemoteAccountResource控制器,
* 以跳过flowable自带的认证系统
* @since 1.0
**/
@RestController
@RequestMapping({
"/app",
"/"
})
public class RemoteAccountResource {
@GetMapping(value = "/rest/account", produces = "application/json")
public UserRepresentation getAccount() {
UserRepresentation user = new UserRepresentation();
user.setId("admin");
user.setFirstName("admin");
user.setLastName("Administrator");
user.setFullName("Test Administrator");
user.setEmail("admin@flowable.org");
user.getPrivileges().add("access-idm");
user.getPrivileges().add("access-rest-api");
user.getPrivileges().add("access-task");
user.getPrivileges().add("access-modeler");
user.getPrivileges().add("access-admin");
// 参考官方提供的响应数据
//return "{\"id\":\"admin\",\"firstName\":\"admin\",\"lastName\":\"Administrator\",\"email\":\"admin@flowable.org\",\"fullName\":\"Test Administrator\",\"groups\":[],\"privileges\":[\"access-idm\",\"access-rest-api\",\"access-task\",\"access-modeler\",\"access-admin\"]}";
return user;
}
}
这样即可在页面中访问了(无需登录)。
相关链接:
SpringBoot集成Flowable modeler设计器-CSDN博客