[jira] [Assigned] (CXF-8077) WSS4JInInterceptor is not thread safe

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[jira] [Assigned] (CXF-8077) WSS4JInInterceptor is not thread safe

JIRA jira@apache.org

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

Colm O hEigeartaigh reassigned CXF-8077:
----------------------------------------

    Assignee: Colm O hEigeartaigh

> WSS4JInInterceptor is not thread safe
> -------------------------------------
>
>                 Key: CXF-8077
>                 URL: https://issues.apache.org/jira/browse/CXF-8077
>             Project: CXF
>          Issue Type: Bug
>          Components: WS-* Components
>    Affects Versions: 3.3.2
>            Reporter: Shumin Li
>            Assignee: Colm O hEigeartaigh
>            Priority: Major
>
> org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor uses a cached property WSSecurityEngine secEngineOverride.  In the situation that the same instance of secEngineOverride is used for 2 or more threads,  Following code in handleMessageInternal() will cause WSS4J to lookup wrong XML document.
> if (soapBody != null) {
>  engine.setCallbackLookup(new CXFCallbackLookup(soapBody.getOwnerDocument(), soapBody));
>  }
> In my case, interceptor is used to do X.509 authentication with Signature for signing. When 2 or more requests comes at the almost the same time, it produces following error for victim thread(s).
> org.apache.cxf.binding.soap.SoapFault: A security error was encountered when verifying the message
>  at org.apache.cxf.ws.security.wss4j.WSS4JUtils.createSoapFault(WSS4JUtils.java:234)
>  at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:376)
>  at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:212)
>  at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:92)
>  at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
>  at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
>  at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
>  at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
>  at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
>  at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
>  at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:216)
>  at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:301)
>  at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:220)
>  at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
>  at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:276)
>  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
>  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
>  at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
>  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
>  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
>  at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:88)
>  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
>  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
>  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
>  at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:209)
>  at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
>  at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
>  at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
>  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
>  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
>  at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
>  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
>  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
>  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
>  at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
>  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
>  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
>  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
>  at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
>  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
>  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
>  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
>  at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:114)
>  at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:104)
>  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
>  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
>  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
>  at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
>  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109)
>  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
>  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
>  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
>  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
>  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
>  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
>  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
>  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
>  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
>  at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
>  at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
>  at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
>  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
>  at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
>  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
>  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
>  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
>  at java.lang.Thread.run(Thread.java:748)
> Caused by: org.apache.wss4j.common.ext.WSSecurityException: javax.xml.crypto.URIReferenceException: org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID id-e41ca583-c6f1-40d5-8acc-f3968287b0cb
>  at org.apache.wss4j.dom.processor.SignatureProcessor.verifyXMLSignature(SignatureProcessor.java:399)
>  at org.apache.wss4j.dom.processor.SignatureProcessor.handleToken(SignatureProcessor.java:232)
>  at org.apache.wss4j.dom.engine.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:340)
>  at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:320)
>  ... 65 common frames omitted
> Caused by: javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID id-e41ca583-c6f1-40d5-8acc-f3968287b0cb
>  at org.apache.jcp.xml.dsig.internal.dom.DOMReference.dereference(DOMReference.java:418)
>  at org.apache.jcp.xml.dsig.internal.dom.DOMReference.validate(DOMReference.java:382)
>  at org.apache.jcp.xml.dsig.internal.dom.DOMXMLSignature.validate(DOMXMLSignature.java:277)
>  at org.apache.wss4j.dom.processor.SignatureProcessor.verifyXMLSignature(SignatureProcessor.java:372)
>  ... 68 common frames omitted
> Caused by: javax.xml.crypto.URIReferenceException: org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID id-e41ca583-c6f1-40d5-8acc-f3968287b0cb
>  at org.apache.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(DOMURIDereferencer.java:117)
>  at org.apache.jcp.xml.dsig.internal.dom.DOMReference.dereference(DOMReference.java:414)
>  ... 71 common frames omitted
> Caused by: org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID id-e41ca583-c6f1-40d5-8acc-f3968287b0cb
>  at org.apache.xml.security.utils.resolver.implementations.ResolverFragment.engineResolveURI(ResolverFragment.java:78)
>  at org.apache.xml.security.utils.resolver.ResourceResolver.resolve(ResourceResolver.java:278)
>  at org.apache.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(DOMURIDereferencer.java:110)
>  ... 72 common frames omitted
>  
> I ended up to override protected WSSecurityEngine getSecurityEngine(boolean utWithCallbacks)  to create WSSecurityEngine everything to avoid the issue.
>  
> It can be fixed using antonymous inner class to replace previous code as following as a concept.  Please note that calling new CXFCallbackLookup(soapBody.getOwnerDocument(), soapBody) in each interface method might not be most efficient.
>  
> final Element soapBody = SAAJUtils.getBody(doc);
>  if (soapBody != null) {
>  engine.setCallbackLookup(new CallbackLookup() {
>  @Override
>  public Element getElement(String s, String s1, boolean b) throws WSSecurityException {
>  return new CXFCallbackLookup(soapBody.getOwnerDocument(), soapBody).getElement(s, s1, b);
>  }
> @Override
>  public Element getAndRegisterElement(String s, String s1, boolean b, DOMCryptoContext domCryptoContext) throws WSSecurityException {
>  return new CXFCallbackLookup(soapBody.getOwnerDocument(), soapBody).getAndRegisterElement(s, s1, b, domCryptoContext);
>  }
> @Override
>  public List<Element> getElements(String s, String s1) throws WSSecurityException {
>  return new CXFCallbackLookup(soapBody.getOwnerDocument(), soapBody).getElements(s, s1);
>  }
> @Override
>  public Element getSOAPBody() {
>  return new CXFCallbackLookup(soapBody.getOwnerDocument(), soapBody).getSOAPBody();
>  }
>  });
>  }



--
This message was sent by Atlassian JIRA
(v7.6.14#76016)