[ 
https://issues.apache.org/jira/browse/CAMEL-10830?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Stephan Siano resolved CAMEL-10830.
-----------------------------------
       Resolution: Fixed
    Fix Version/s: 2.19.0

> 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
>             Fix For: 2.19.0
>
>
> 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)

Reply via email to