Repository: cxf Updated Branches: refs/heads/master 6c118849e -> dc8b98085
[CXF-6209][CXF-6210] - Bug in processing Signed/Encrypted Elements policies with multiple XPaths - XPath evaluation failure on the client side causes all subsequent evaluations to fail Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/dc8b9808 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/dc8b9808 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/dc8b9808 Branch: refs/heads/master Commit: dc8b98085c95692cd632047c2d4f8d222c78bfb7 Parents: 6c11884 Author: Colm O hEigeartaigh <cohei...@apache.org> Authored: Tue Jan 20 15:04:00 2015 +0000 Committer: Colm O hEigeartaigh <cohei...@apache.org> Committed: Tue Jan 20 15:04:29 2015 +0000 ---------------------------------------------------------------------- .../wss4j/PolicyBasedWSS4JInInterceptor.java | 12 +-- .../policyhandlers/AbstractBindingBuilder.java | 82 ++++++++++---------- .../policyhandlers/TransportBindingHandler.java | 14 +--- .../apache/cxf/systest/ws/parts/PartsTest.java | 50 ++++++++++++ .../cxf/systest/ws/parts/DoubleItParts.wsdl | 3 + .../org/apache/cxf/systest/ws/parts/client.xml | 15 ++++ .../multiple-encrypted-elements-policy.xml | 48 ++++++++++++ .../org/apache/cxf/systest/ws/parts/server.xml | 14 ++++ 8 files changed, 183 insertions(+), 55 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java index f118eeb..fd636c3 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java @@ -555,15 +555,17 @@ public class PolicyBasedWSS4JInInterceptor extends WSS4JInInterceptor { if (elements != null && elements.getXPaths() != null && !elements.getXPaths().isEmpty()) { List<String> expressions = new ArrayList<String>(); + MapNamespaceContext namespaceContext = new MapNamespaceContext(); + for (org.apache.wss4j.policy.model.XPath xPath : elements.getXPaths()) { expressions.add(xPath.getXPath()); + Map<String, String> namespaceMap = xPath.getPrefixNamespaceMap(); + if (namespaceMap != null) { + namespaceContext.addNamespaces(namespaceMap); + } } - if (elements.getXPaths().get(0).getPrefixNamespaceMap() != null) { - xpath.setNamespaceContext( - new MapNamespaceContext(elements.getXPaths().get(0).getPrefixNamespaceMap()) - ); - } + xpath.setNamespaceContext(namespaceContext); try { CryptoCoverageUtil.checkCoverage(soapEnvelope, refs, xpath, expressions, type, scope); http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java index 87e6cb6..a697e41 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java @@ -1194,21 +1194,12 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle // Handle sign/enc parts result.addAll(this.getParts(sign, includeBody, parts, found)); - // Handle sign/enc elements - try { - result.addAll(this.getElements("Element", xpaths, found, sign)); - } catch (XPathExpressionException e) { - LOG.log(Level.FINE, e.getMessage(), e); - // REVISIT - } + result.addAll(this.getElements("Element", xpaths, found, sign)); - // Handle content encrypted elements - try { + if (!sign) { + // Handle content encrypted elements result.addAll(this.getElements("Content", contentXpaths, found, sign)); - } catch (XPathExpressionException e) { - LOG.log(Level.FINE, e.getMessage(), e); - // REVISIT } return result; @@ -1323,7 +1314,7 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle protected List<WSEncryptionPart> getElements(String encryptionModifier, List<org.apache.wss4j.policy.model.XPath> xpaths, List<Element> found, - boolean forceId) throws XPathExpressionException, SOAPException { + boolean forceId) throws SOAPException { List<WSEncryptionPart> result = new ArrayList<WSEncryptionPart>(); @@ -1335,33 +1326,27 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle xpath.setNamespaceContext(new MapNamespaceContext(xPath.getPrefixNamespaceMap())); } - NodeList list = (NodeList)xpath.evaluate(xPath.getXPath(), saaj.getSOAPPart().getEnvelope(), - XPathConstants.NODESET); - for (int x = 0; x < list.getLength(); x++) { - Element el = (Element)list.item(x); - - if (!found.contains(el)) { - String id = null; - if (forceId) { - id = this.addWsuIdToElement(el); - } else { - //not forcing an ID on this. Use one if there is one - //there already, but don't force one - Attr idAttr = el.getAttributeNodeNS(null, "Id"); - if (idAttr == null) { - //then try the wsu:Id value - idAttr = el.getAttributeNodeNS(PolicyConstants.WSU_NAMESPACE_URI, "Id"); - } - if (idAttr != null) { - id = idAttr.getValue(); - } - } - WSEncryptionPart part = - new WSEncryptionPart(id, encryptionModifier); - part.setElement(el); - part.setXpath(xPath.getXPath()); + NodeList list = null; + try { + list = (NodeList)xpath.evaluate(xPath.getXPath(), saaj.getSOAPPart().getEnvelope(), + XPathConstants.NODESET); + } catch (XPathExpressionException e) { + LOG.log(Level.WARNING, "Failure in evaluating an XPath expression", e); + } + + if (list != null) { + for (int x = 0; x < list.getLength(); x++) { + Element el = (Element)list.item(x); - result.add(part); + if (!found.contains(el)) { + String id = setIdOnElement(el, forceId); + WSEncryptionPart part = + new WSEncryptionPart(id, encryptionModifier); + part.setElement(el); + part.setXpath(xPath.getXPath()); + + result.add(part); + } } } } @@ -1370,6 +1355,25 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle return result; } + private String setIdOnElement(Element element, boolean forceId) { + if (forceId) { + return this.addWsuIdToElement(element); + } + + //not forcing an ID on this. Use one if there is one + //there already, but don't force one + Attr idAttr = element.getAttributeNodeNS(null, "Id"); + if (idAttr == null) { + //then try the wsu:Id value + idAttr = element.getAttributeNodeNS(PolicyConstants.WSU_NAMESPACE_URI, "Id"); + } + if (idAttr != null) { + return idAttr.getValue(); + } + + return null; + } + protected WSSecEncryptedKey getEncryptedKeyBuilder(AbstractTokenWrapper wrapper, AbstractToken token) throws WSSecurityException { WSSecEncryptedKey encrKey = new WSSecEncryptedKey(wssConfig); http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java index bc90e3c..5947969 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java @@ -28,7 +28,6 @@ import java.util.logging.Level; import javax.xml.crypto.dsig.Reference; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPMessage; -import javax.xml.xpath.XPathExpressionException; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -639,16 +638,9 @@ public class TransportBindingHandler extends AbstractBindingBuilder { if (signedElements != null) { // Handle SignedElements - try { - result.addAll( - this.getElements( - "Element", signedElements.getXPaths(), found, true - ) - ); - } catch (XPathExpressionException e) { - LOG.log(Level.FINE, e.getMessage(), e); - // REVISIT - } + result.addAll( + this.getElements("Element", signedElements.getXPaths(), found, true) + ); } return result; http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/parts/PartsTest.java ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/parts/PartsTest.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/parts/PartsTest.java index b1bbeb1..1b0b3b8 100644 --- a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/parts/PartsTest.java +++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/parts/PartsTest.java @@ -436,6 +436,56 @@ public class PartsTest extends AbstractBusClientServerTestBase { } @org.junit.Test + public void testMultipleEncryptedElements() throws Exception { + + if (test.isStreaming() || STAX_PORT.equals(test.getPort())) { + return; + } + + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = PartsTest.class.getResource("client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + URL wsdl = PartsTest.class.getResource("DoubleItParts.wsdl"); + Service service = Service.create(wsdl, SERVICE_QNAME); + + // Successful invocation + QName portQName = new QName(NAMESPACE, "DoubleItEncryptedElementsPort3"); + DoubleItPortType port = service.getPort(portQName, DoubleItPortType.class); + updateAddressPort(port, test.getPort()); + + if (test.isStreaming()) { + SecurityTestUtil.enableStreaming(port); + } + + port.doubleIt(25); + + // This should fail, as the service requires that the header must be encrypted + portQName = new QName(NAMESPACE, "DoubleItEncryptedElementsPort2"); + port = service.getPort(portQName, DoubleItPortType.class); + updateAddressPort(port, test.getPort()); + + if (test.isStreaming()) { + SecurityTestUtil.enableStreaming(port); + } + + try { + port.doubleIt(25); + fail("Failure expected on a header which isn't encrypted"); + } catch (javax.xml.ws.soap.SOAPFaultException ex) { + String error = "EncryptedElements"; + assertTrue(ex.getMessage().contains(error) + || ex.getMessage().contains("To must be encrypted")); + } + + ((java.io.Closeable)port).close(); + bus.shutdown(true); + } + + @org.junit.Test public void testContentEncryptedElements() throws Exception { SpringBusFactory bf = new SpringBusFactory(); http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl index 2981c36..645def6 100644 --- a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl +++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl @@ -100,6 +100,9 @@ <wsdl:port name="DoubleItEncryptedElementsPort2" binding="tns:DoubleItStandardBinding"> <soap:address location="http://localhost:9010/DoubleItEncryptedElements2"/> </wsdl:port> + <wsdl:port name="DoubleItEncryptedElementsPort3" binding="tns:DoubleItStandardBinding"> + <soap:address location="http://localhost:9010/DoubleItEncryptedElements3"/> + </wsdl:port> <wsdl:port name="DoubleItContentEncryptedElementsPort" binding="tns:DoubleItStandardBinding"> <soap:address location="http://localhost:9010/DoubleItContentEncryptedElements"/> </wsdl:port> http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/client.xml ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/client.xml b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/client.xml index d49de99..6aa97be 100644 --- a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/client.xml +++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/client.xml @@ -234,6 +234,21 @@ </p:policies> </jaxws:features> </jaxws:client> + <jaxws:client name="{http://www.example.org/contract/DoubleIt}DoubleItEncryptedElementsPort3" createdFromAPI="true"> + <jaxws:properties> + <entry key="ws-security.username" value="Alice"/> + <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.common.UTPasswordCallback"/> + <entry key="ws-security.encryption.properties" value="bob.properties"/> + <entry key="ws-security.encryption.username" value="bob"/> + <entry key="ws-security.signature.properties" value="alice.properties"/> + <entry key="ws-security.signature.username" value="alice"/> + </jaxws:properties> + <jaxws:features> + <p:policies> + <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy" URI="classpath:/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml"/> + </p:policies> + </jaxws:features> + </jaxws:client> <jaxws:client name="{http://www.example.org/contract/DoubleIt}DoubleItContentEncryptedElementsPort" createdFromAPI="true"> <jaxws:properties> <entry key="ws-security.username" value="Alice"/> http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml new file mode 100644 index 0000000..a75f6fd --- /dev/null +++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<wsp:Policy xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" wsu:Id="RequiredPartsPolicy"> + <wsp:ExactlyOne> + <wsp:All> + <sp:AsymmetricBinding xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> + <wsp:Policy> + <sp:InitiatorToken> + <wsp:Policy> + <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> + <wsp:Policy> + <sp:WssX509V3Token10/> + </wsp:Policy> + </sp:X509Token> + </wsp:Policy> + </sp:InitiatorToken> + <sp:RecipientToken> + <wsp:Policy> + <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never"> + <wsp:Policy> + <sp:WssX509V3Token10/> + <sp:RequireIssuerSerialReference/> + </wsp:Policy> + </sp:X509Token> + </wsp:Policy> + </sp:RecipientToken> + <sp:Layout> + <wsp:Policy> + <sp:Lax/> + </wsp:Policy> + </sp:Layout> + <sp:AlgorithmSuite> + <wsp:Policy> + <sp:Basic128/> + </wsp:Policy> + </sp:AlgorithmSuite> + </wsp:Policy> + </sp:AsymmetricBinding> + <sp:EncryptedElements xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> + <sp:XPath xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">/soap:Envelope/soap:Header/wsa:To</sp:XPath> + <sp:XPath xmlns:example1="http://www.example.org/schema/DoubleIt">//example1:DoubleIt</sp:XPath> + </sp:EncryptedElements> + <sp:SignedParts xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> + <sp:Body/> + </sp:SignedParts> + <wsaws:UsingAddressing xmlns:wsaws="http://www.w3.org/2006/05/addressing/wsdl"/> + </wsp:All> + </wsp:ExactlyOne> +</wsp:Policy> http://git-wip-us.apache.org/repos/asf/cxf/blob/dc8b9808/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/server.xml ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/server.xml b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/server.xml index 6616f10..40f10f1 100644 --- a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/server.xml +++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/parts/server.xml @@ -212,6 +212,20 @@ </p:policies> </jaxws:features> </jaxws:endpoint> + <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="EncryptedElements3" address="http://localhost:${testutil.ports.Server}/DoubleItEncryptedElements3" serviceName="s:DoubleItService" endpointName="s:DoubleItEncryptedElementsPort3" implementor="org.apache.cxf.systest.ws.common.DoubleItImpl" wsdlLocation="org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl"> + <jaxws:properties> + <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.common.UTPasswordCallback"/> + <entry key="ws-security.signature.properties" value="bob.properties"/> + <entry key="ws-security.encryption.username" value="alice"/> + <entry key="ws-security.encryption.properties" value="alice.properties"/> + <entry key="ws-security.subject.cert.constraints" value=".*O=apache.org.*"/> + </jaxws:properties> + <jaxws:features> + <p:policies> + <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy" URI="classpath:/org/apache/cxf/systest/ws/parts/multiple-encrypted-elements-policy.xml"/> + </p:policies> + </jaxws:features> + </jaxws:endpoint> <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="ContentEncryptedElements" address="http://localhost:${testutil.ports.Server}/DoubleItContentEncryptedElements" serviceName="s:DoubleItService" endpointName="s:DoubleItContentEncryptedElementsPort" implementor="org.apache.cxf.systest.ws.common.DoubleItImpl" wsdlLocation="org/apache/cxf/systest/ws/parts/DoubleItParts.wsdl"> <jaxws:properties> <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.common.UTPasswordCallback"/>