I have implemented token-based authentication using WebSecurityConfig
, and two custom Filter. I was able to test REST with custom header with no issues. But when I incorporated Camunda webapp, I am geting login page with username and password. Is there a way to add another filter to use token-based authentication which webapp can use to gain access to cockpit and other services directly.
Consider my implementation below:
WebSecurityConfig.java
:
@Configuration
@EnableWebSecurity
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private String headerKey="userId";
private String headerValue="token";
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
http
.addFilter(preAuthFilter())
.antMatcher("/**")
.csrf()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
@Bean
public PreAuthFilter preAuthFilter() throws Exception {
PreAuthFilter preAuthFilter = new PreAuthFilter(headerKey);
preAuthFilter.setAuthenticationManager(authenticationManagerBean());
return preAuthFilter;
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return authentication -> {
String principal = (String) authentication.getPrincipal();
if (!headerValue.equals(principal))
{
throw new BadCredentialsException("The API key was not found "
+ "or not the expected value!");
}
authentication.setAuthenticated(true);
return authentication;
};
}
PreAuthFilter
:
@Order(2)
public class PreAuthFilter extends AbstractPreAuthenticatedProcessingFilter implements Filter {
private String headerKey;
public PreAuthFilter(String headerKey) {
this.headerKey = headerKey;
}
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
return request.getHeader(headerKey);
}
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
return "N/A";
}
}
CustomAuthenticationFilter
:
@Order(1)
public class GroupAuthenticationFilter implements Filter{
private List<String> groupIds; // Fetching groupId from other class
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@SneakyThrows
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
ProcessEngine processEngine = EngineUtil.lookupProcessEngine("default");
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String userId = principal.toString();
try {
processEngine.getIdentityService().setAuthentication(userId, groupIds);
chain.doFilter(request, response); // Error
} finally {
clearAuthentication(processEngine);
}
}
private void clearAuthentication(ProcessEngine engine) {
engine.getIdentityService().clearAuthentication();
}
@Override
public void destroy() {
}
}