SpringBoot整合Flowable modeler设计器

本文详细介绍了如何在SpringBoot项目中使用Flowable的流程引擎和在线工作流设计器,版本6.8.0,以及如何设置Modeler跳过内置安全认证,提供自定义的用户信息获取和权限控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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博客

Spring Boot整合流程引擎Flowable_flowable springboot-CSDN博客

Flowable BPMN 用户手册 (v 6.3.0)

BPMN流程图在线制作-支持flowable,activit,camunda三种工作流引擎_bpmn在线-CSDN博客

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值