The context is confused when using ContextPropagator to pass the ThreadLocal context

Hi, I use ContextPropagator to pass the username which serialize from the spring security context holder.

And deserialize the username then set it to spring security context holder.But sometime the child workflow’s user is different with parent workflow, it should be same.

For example,user A start a workflow wfA, user B start a workflow wfB when wfA is about to end.
The wfB’s child workflow wfB1’s user will be user A sometimes.

I can’t figure out what happened. Shouldn’t i use ContextPropagator for my purpose?

The following is my ContextPropagator code:

public class SpringSecurityContextPropagators implements ContextPropagator {

    public SpringSecurityContextPropagators(UserContext userContext){
        this.userContext = userContext;

    private UserContext userContext;

    public final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
    private static final String PROPAGATOR_KEY = "username";

    public String getName() {
        return this.getClass().getName();

    public Map<String, Payload> serializeContext(Object context) {
        if (context == null) {
            return Collections.emptyMap();
        Map<String, Payload> serializedContext = new HashMap<>();
        serializedContext.put(PROPAGATOR_KEY, Payload.newBuilder().setData(ByteString.copyFromUtf8((String) context)).build());
        return serializedContext;

    public Object deserializeContext(Map<String, Payload> context) {
        Payload payload = context.get(PROPAGATOR_KEY);
        return payload == null ? null : payload.getData().toStringUtf8();

    public Object getCurrentContext() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            logger.warn("auth info is empty!");
            return null;
        return ((UserDetails) authentication.getPrincipal()).getUsername();

    public void setCurrentContext(Object context) {
        if (context == null) {
        userContext.loadAuthenticationByUsername((String) context);
1 Like

Using Interceptors is preferred over context propagator in most cases.
You can see interceptors use in the Java SDK OpenTracing module, and small sample here.

My guess is that your problem is not linked to the ContextPropagator, but how SecurityContextHolder interacts with the workflow threads.

Thanks for the reply, I will give a try using Interceptors.

Yes, My problem is how SecurityContextHolder interacts with not only the workflow threads but also activity threads.
I think I can use ContextPropagator to do it, but it not worked as expected.
I will try using Interceptors to make it as tihomir says.