SSO (Spring Security + Camunda Identity Service)


#1

Hi,

I have implemented spring security within a spring boot app that embed camunda-bpm-spring-boot-webapp dependency.
Then authentication is made using a custom authentication provider against identityService.checkPassword and identityService.setAuthenticationUserId.

How to SSO the embed Camunda Webapp? now i logged in successfuly using registered Camunda users and password, but when trying to open Camunda Tasklist/Welcome/Admin it redirects to Camunda common Login page.

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication auth) 
      throws AuthenticationException {
        String username = auth.getName();
        String password = auth.getCredentials()
            .toString();
        
        CamundaUtils cm = new CamundaUtils();
        if (cm.signin(username, password)) {
            return new UsernamePasswordAuthenticationToken
              (username, password, Collections.emptyList());
        } else {
            throw new
              BadCredentialsException("External system authentication failed");
        }
    }
 
    @Override
    public boolean supports(Class<?> auth) {
        return auth.equals(UsernamePasswordAuthenticationToken.class);
    }
}

#CamundaUtils

public boolean signin(String userId, String password) {
		boolean isValid = identityService.checkPassword(userId, password);
		if(isValid) identityService.setAuthenticatedUserId(userId);
		return isValid;
	}

Regards,
Hendry


#2

Hi,

The SSO works when i use Container-Based Authentication, i follow the git project:

However i noticed that the signout button inside the Camunda Webapp does not work, and Authorization seems to be not working as well (cannot see available applications in Camunda Welcome, and a Spring Whitelabel error when opening tasklisk). I suspect the container still has authenticated state.
Please adviceā€¦

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Bean
    public FilterRegistrationBean containerBasedAuthenticationFilter(){

        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new ContainerBasedAuthenticationFilter());
        filterRegistration.setInitParameters(Collections.singletonMap("authentication-provider", "com.ey.eyharmony.config.SpringSecurityAuthenticationProvider"));
        filterRegistration.setOrder(101); // make sure the filter is registered after the Spring Security Filter Chain
        filterRegistration.addUrlPatterns("/app/*");
        return filterRegistration;
    }
	
	@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
//                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll()
                .and()
                .csrf().ignoringAntMatchers("/app/","/lib/","/api/**");
    }
}

#Custom Provider

public class SpringSecurityAuthenticationProvider extends ContainerBasedAuthenticationProvider {

    @Override
    public AuthenticationResult extractAuthenticatedUser(HttpServletRequest request, ProcessEngine engine) {

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication == null) {
            return AuthenticationResult.unsuccessful();
        }

        String name = authentication.getName();
        if (name == null || name.isEmpty()) {
            return AuthenticationResult.unsuccessful();
        }

        AuthenticationResult authenticationResult = new AuthenticationResult(name, true);
        authenticationResult.setGroups(getUserGroups(authentication));

        return authenticationResult;
    }

    private List<String> getUserGroups(Authentication authentication){

        List<String> groupIds;

        groupIds = authentication.getAuthorities().stream()
                .map(res -> res.getAuthority())
                .map(res -> res.substring(5)) // Strip "ROLE_"
                .collect(Collectors.toList());

        return groupIds;

    }

}

Regards,
Hendry