Author: coheigea Date: Mon Oct 8 13:02:31 2012 New Revision: 1395540 URL: http://svn.apache.org/viewvc?rev=1395540&view=rev Log: Merged revisions 1395535 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/branches/2.5.x-fixes
........ r1395535 | coheigea | 2012-10-08 13:56:31 +0100 (Mon, 08 Oct 2012) | 18 lines Merged revisions 1395526 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/branches/2.6.x-fixes ........ r1395526 | coheigea | 2012-10-08 13:30:23 +0100 (Mon, 08 Oct 2012) | 10 lines Merged revisions 1395514 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/trunk ........ r1395514 | coheigea | 2012-10-08 12:04:21 +0100 (Mon, 08 Oct 2012) | 2 lines Speed-up XPath evaluation for WS-Security code coverage checking ........ ........ ........ Modified: cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageChecker.java cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java Modified: cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageChecker.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageChecker.java?rev=1395540&r1=1395539&r2=1395540&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageChecker.java (original) +++ cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageChecker.java Mon Oct 8 13:02:31 2012 @@ -20,6 +20,7 @@ package org.apache.cxf.ws.security.wss4j import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -30,6 +31,8 @@ import java.util.Vector; import javax.xml.namespace.QName; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPMessage; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathFactory; import org.w3c.dom.Element; @@ -37,6 +40,7 @@ import org.apache.cxf.binding.soap.SoapF import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.helpers.MapNamespaceContext; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.Phase; import org.apache.cxf.ws.security.wss4j.CryptoCoverageUtil.CoverageScope; @@ -164,42 +168,54 @@ public class CryptoCoverageChecker exten CryptoCoverageUtil.reconcileEncryptedSignedRefs(signed, encrypted); - for (XPathExpression xPathExpression : this.xPaths) { - Collection<WSDataRef> refsToCheck = null; - - switch (xPathExpression.getType()) { - case SIGNED: - refsToCheck = signed; - break; - case ENCRYPTED: - refsToCheck = encrypted; - break; - default: - throw new IllegalStateException("Unexpected crypto type: " - + xPathExpression.getType()); - } + if (this.xPaths != null && !this.xPaths.isEmpty()) { + // XPathFactory and XPath are not thread-safe so we must recreate them + // each request. + final XPathFactory factory = XPathFactory.newInstance(); + final XPath xpath = factory.newXPath(); + + if (this.prefixMap != null) { + xpath.setNamespaceContext(new MapNamespaceContext(this.prefixMap)); + } + + for (XPathExpression xPathExpression : this.xPaths) { + Collection<WSDataRef> refsToCheck = null; + + switch (xPathExpression.getType()) { + case SIGNED: + refsToCheck = signed; + break; + case ENCRYPTED: + refsToCheck = encrypted; + break; + default: + throw new IllegalStateException("Unexpected crypto type: " + + xPathExpression.getType()); + } + + try { + SOAPMessage saajDoc = message.getContent(SOAPMessage.class); + Element documentElement = null; + if (saajDoc != null && saajDoc.getSOAPPart() != null) { + documentElement = saajDoc.getSOAPPart().getEnvelope(); + } - try { - SOAPMessage saajDoc = message.getContent(SOAPMessage.class); - Element documentElement = null; - if (saajDoc != null && saajDoc.getSOAPPart() != null) { - documentElement = saajDoc.getSOAPPart().getEnvelope(); + CryptoCoverageUtil.checkCoverage( + documentElement, + refsToCheck, + xpath, + Arrays.asList(xPathExpression.getXPath()), + xPathExpression.getType(), + xPathExpression.getScope()); + } catch (WSSecurityException e) { + throw new SoapFault("No " + xPathExpression.getType() + + " element found matching XPath " + + xPathExpression.getXPath(), Fault.FAULT_CODE_CLIENT); + } catch (SOAPException e) { + throw new SoapFault("No " + xPathExpression.getType() + + " element found matching XPath " + + xPathExpression.getXPath(), Fault.FAULT_CODE_CLIENT); } - CryptoCoverageUtil.checkCoverage( - documentElement, - refsToCheck, - this.prefixMap, - xPathExpression.getXPath(), - xPathExpression.getType(), - xPathExpression.getScope()); - } catch (WSSecurityException e) { - throw new SoapFault("No " + xPathExpression.getType() - + " element found matching XPath " - + xPathExpression.getXPath(), Fault.FAULT_CODE_CLIENT); - } catch (SOAPException e) { - throw new SoapFault("No " + xPathExpression.getType() - + " element found matching XPath " - + xPathExpression.getXPath(), Fault.FAULT_CODE_CLIENT); } } } Modified: cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java?rev=1395540&r1=1395539&r2=1395540&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java (original) +++ cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java Mon Oct 8 13:02:31 2012 @@ -256,6 +256,23 @@ public final class CryptoCoverageUtil { xpath.setNamespaceContext(new MapNamespaceContext(namespaces)); } + checkCoverage(soapEnvelope, refs, xpath, xPaths, type, scope); + } + + /** + * Checks that the references provided refer to the required + * signed/encrypted elements as defined by the XPath expressions in {@code + * xPaths}. + */ + public static void checkCoverage( + Element soapEnvelope, + final Collection<WSDataRef> refs, + final XPath xpath, + Collection<String> xPaths, + CoverageType type, + CoverageScope scope + ) throws WSSecurityException { + // For each XPath for (String xpathString : xPaths) { // Get the matching nodes Modified: cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java?rev=1395540&r1=1395539&r2=1395540&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java (original) +++ cxf/branches/2.4.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java Mon Oct 8 13:02:31 2012 @@ -388,10 +388,10 @@ public class PolicyBasedWSS4JInIntercept private boolean assertXPathTokens(AssertionInfoMap aim, QName name, Collection<WSDataRef> refs, - SoapMessage msg, Element soapEnvelope, CoverageType type, - CoverageScope scope) throws SOAPException { + CoverageScope scope, + final XPath xpath) throws SOAPException { Collection<AssertionInfo> ais = aim.get(name); if (ais != null) { for (AssertionInfo ai : ais) { @@ -409,9 +409,12 @@ public class PolicyBasedWSS4JInIntercept } if (xpaths != null) { + if (namespaces != null) { + xpath.setNamespaceContext(new MapNamespaceContext(namespaces)); + } try { CryptoCoverageUtil.checkCoverage(soapEnvelope, refs, - namespaces, xpaths, type, scope); + xpath, xpaths, type, scope); } catch (WSSecurityException e) { ai.setNotAsserted("No " + type + " element found matching one of the XPaths " @@ -586,12 +589,19 @@ public class PolicyBasedWSS4JInIntercept ); } Element soapEnvelope = soapHeader.getOwnerDocument().getDocumentElement(); - check &= assertXPathTokens(aim, SP12Constants.SIGNED_ELEMENTS, signed, msg, soapEnvelope, - CoverageType.SIGNED, CoverageScope.ELEMENT); - check &= assertXPathTokens(aim, SP12Constants.ENCRYPTED_ELEMENTS, encrypted, msg, soapEnvelope, - CoverageType.ENCRYPTED, CoverageScope.ELEMENT); - check &= assertXPathTokens(aim, SP12Constants.CONTENT_ENCRYPTED_ELEMENTS, encrypted, msg, - soapEnvelope, CoverageType.ENCRYPTED, CoverageScope.CONTENT); + if (containsXPathPolicy(aim)) { + // XPathFactory and XPath are not thread-safe so we must recreate them + // each request. + final XPathFactory factory = XPathFactory.newInstance(); + final XPath xpath = factory.newXPath(); + + check &= assertXPathTokens(aim, SP12Constants.SIGNED_ELEMENTS, signed, soapEnvelope, + CoverageType.SIGNED, CoverageScope.ELEMENT, xpath); + check &= assertXPathTokens(aim, SP12Constants.ENCRYPTED_ELEMENTS, encrypted, soapEnvelope, + CoverageType.ENCRYPTED, CoverageScope.ELEMENT, xpath); + check &= assertXPathTokens(aim, SP12Constants.CONTENT_ENCRYPTED_ELEMENTS, encrypted, + soapEnvelope, CoverageType.ENCRYPTED, CoverageScope.CONTENT, xpath); + } check &= assertHeadersExists(aim, msg, soapHeader); return check; @@ -804,5 +814,21 @@ public class PolicyBasedWSS4JInIntercept } return false; } + + private boolean containsXPathPolicy(AssertionInfoMap aim) { + Collection<AssertionInfo> ais = aim.get(SP12Constants.SIGNED_ELEMENTS); + if (ais != null && ais.size() > 0) { + return true; + } + ais = aim.get(SP12Constants.ENCRYPTED_ELEMENTS); + if (ais != null && ais.size() > 0) { + return true; + } + ais = aim.get(SP12Constants.CONTENT_ENCRYPTED_ELEMENTS); + if (ais != null && ais.size() > 0) { + return true; + } + return false; + } }
