Embedded Frontend
Flowable Engage provides a dedicated JavaScript frontend that can either be deployed to any HTML capable server or run embedded directly within the Flowable Server.
To run the frontend embedded within the Flowable Server add the
following dependency to the pom.xml
file of the project:
<dependency>
<groupId>com.flowable.work</groupId>
<artifactId>flowable-work-frontend</artifactId>
</dependency>
The frontend provides user interfaces for both Flowable Work and Flowable Engage. The Engage interface can be deactivated if only Work features are made available. |
In addition you need to provide the correct Spring Boot Security
configuration to allow access to the embedded frontend.
This is done by adding a class e.g. called SecurityConfiguration
as a sibling
of the Spring Boot Application class containing the following configuration:
import com.flowable.platform.common.security.SecurityConstants;
import com.flowable.core.spring.security.web.authentication.AjaxAuthenticationFailureHandler;
import com.flowable.core.spring.security.web.authentication.AjaxAuthenticationSuccessHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
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.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
@Configuration
@Order(10)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.headers().frameOptions().sameOrigin()
.and()
.logout()
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
.logoutUrl("/auth/logout")
.and()
.exceptionHandling()
.defaultAuthenticationEntryPointFor(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), AnyRequestMatcher.INSTANCE)
.and()
.formLogin()
.loginProcessingUrl("/auth/login")
.successHandler(new AjaxAuthenticationSuccessHandler())
.failureHandler(new AjaxAuthenticationFailureHandler())
.and()
.authorizeRequests()
.antMatchers("/analytics-api/**").hasAuthority(SecurityConstants.ACCESS_REPORTS_METRICS)
.antMatchers("/template-api/**").hasAuthority(SecurityConstants.ACCESS_TEMPLATE_MANAGEMENT)
.antMatchers("/work-object-api/**").hasAuthority(SecurityConstants.ACCESS_WORKOBJECT_API)
// allow context root for all (it triggers the loading of the initial page)
.antMatchers("/") .permitAll()
.antMatchers(
"/**/*.svg", "/**/*.ico", "/**/*.png", "/**/*.woff2", "/**/*.css",
"/**/*.woff", "/**/*.html", "/**/*.js",
"/**/index.html").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}