You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Stephan Siano (JIRA)" <ji...@apache.org> on 2017/02/15 07:47:41 UTC

[jira] [Created] (CAMEL-10830) Race condition when reading principal for one-way web services

Stephan Siano created CAMEL-10830:
-------------------------------------

             Summary: Race condition when reading principal for one-way web services
                 Key: CAMEL-10830
                 URL: https://issues.apache.org/jira/browse/CAMEL-10830
             Project: Camel
          Issue Type: Bug
          Components: camel-cxf
    Affects Versions: 2.16.2
            Reporter: Stephan Siano
            Assignee: Stephan Siano
            Priority: Minor


This is an issue of the more esoteric kind.

If camel-cxf is running on Tomcat 7 and the provided web service is a one-way webservice and if the robust feature is not set in very rare cases the following exception can occur:
{noformat}
nowjava.lang.SecurityException: attempting to add an object which is not an instance of java.security.Principal to a Subject's Principal Set
        at javax.security.auth.Subject$SecureSet.add(Subject.java:1106)
        at java.util.Collections$SynchronizedCollection.add(Collections.java:1636)
        at org.apache.camel.component.cxf.DefaultCxfBinding.populateExchangeFromCxfRequest(DefaultCxfBinding.java:275)
        at org.apache.camel.component.cxf.CxfConsumer$1.prepareCamelExchange(CxfConsumer.java:187)
        at org.apache.camel.component.cxf.CxfConsumer$1.syncInvoke(CxfConsumer.java:132)
        at org.apache.camel.component.cxf.CxfConsumer$1.invoke(CxfConsumer.java:78)
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor$2.run(ServiceInvokerInterceptor.java:126)
        at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:131)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
        at org.apache.cxf.phase.PhaseInterceptorChain.resume(PhaseInterceptorChain.java:278)
        at org.apache.cxf.interceptor.OneWayProcessorInterceptor$1.run(OneWayProcessorInterceptor.java:137)
        at org.apache.cxf.workqueue.AutomaticWorkQueueImpl$3.run(AutomaticWorkQueueImpl.java:428)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at org.apache.cxf.workqueue.AutomaticWorkQueueImpl$AWQThreadFactory$1.run(AutomaticWorkQueueImpl.java:353)
        at java.lang.Thread.run(Thread.java:807)
{noformat}

The reason for that is in the combination of this code
{code:title=DefaultCxfBinding.java}
        if (securityContext instanceof LoginSecurityContext
            && ((LoginSecurityContext)securityContext).getSubject() != null) {
            camelExchange.getIn().getHeaders().put(Exchange.AUTHENTICATION, 
                                                   ((LoginSecurityContext)securityContext).getSubject());
        } else if (securityContext != null && securityContext.getUserPrincipal() != null) {
            Subject subject = new Subject();
            subject.getPrincipals().add(securityContext.getUserPrincipal());
            camelExchange.getIn().getHeaders().put(Exchange.AUTHENTICATION, subject);
        }
{code}
with the implementation of the CXF securtyContext, the way Tomcat implements the login context, and the thread context change created by CXF for the one-way web services. As a result the behaviour of securityContext.getUserPrincipal() may change asynchonously at any time (so it may return a principal when the null check happens and may return null on the second call). Trying to add null to the principals will create above exception.

The fix for this is to call getUserPrincipal() only once and perform the null check and the add() operation with the result.

Obviously the issue is not testable (because even in the environment where this may happen it is very improbable that it can be reproduced).



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)