You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2012/10/08 13:04:22 UTC

svn commit: r1395514 - in /cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j: CryptoCoverageChecker.java CryptoCoverageUtil.java PolicyBasedWSS4JInInterceptor.java

Author: coheigea
Date: Mon Oct  8 11:04:21 2012
New Revision: 1395514

URL: http://svn.apache.org/viewvc?rev=1395514&view=rev
Log:
Speed-up XPath evaluation for WS-Security code coverage checking

Modified:
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageChecker.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java
    cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java

Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageChecker.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageChecker.java?rev=1395514&r1=1395513&r2=1395514&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageChecker.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageChecker.java Mon Oct  8 11:04:21 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/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java?rev=1395514&r1=1395513&r2=1395514&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/CryptoCoverageUtil.java Mon Oct  8 11:04:21 2012
@@ -254,6 +254,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/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java?rev=1395514&r1=1395513&r2=1395514&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java Mon Oct  8 11:04:21 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;
+    }
 
 }