You are viewing a plain text version of this content. The canonical link for it is here.
Posted to wss4j-dev@ws.apache.org by co...@apache.org on 2009/04/29 15:38:24 UTC

svn commit: r769785 - in /webservices/wss4j/branches/1_5_x-fixes: src/org/apache/ws/security/message/token/ src/org/apache/ws/security/transform/ src/org/apache/ws/security/util/ test/wssec/

Author: coheigea
Date: Wed Apr 29 13:38:23 2009
New Revision: 769785

URL: http://svn.apache.org/viewvc?rev=769785&view=rev
Log:
[WSS-178] - Backported fix to 1_5_x-fixes branch.

Added:
    webservices/wss4j/branches/1_5_x-fixes/test/wssec/TestWSSecurityWSS178.java
      - copied unchanged from r769781, webservices/wss4j/trunk/test/wssec/TestWSSecurityWSS178.java
Modified:
    webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/message/token/SecurityTokenReference.java
    webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/transform/STRTransform.java
    webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/util/WSSecurityUtil.java
    webservices/wss4j/branches/1_5_x-fixes/test/wssec/PackageTests.java

Modified: webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/message/token/SecurityTokenReference.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/message/token/SecurityTokenReference.java?rev=769785&r1=769784&r2=769785&view=diff
==============================================================================
--- webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/message/token/SecurityTokenReference.java (original)
+++ webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/message/token/SecurityTokenReference.java Wed Apr 29 13:38:23 2009
@@ -150,69 +150,9 @@
                 WSSecurityException.INVALID_SECURITY, "badReferenceURI"
             );
         }
-        Element tokElement = null;
-        String tmpS = WSConstants.WSS_SAML_NS + WSConstants.WSS_SAML_ASSERTION;
-        String saml10 = WSConstants.WSS_SAML_NS + WSConstants.SAML_ASSERTION_ID;
-        if (tmpS.equals(ref.getValueType())
-            || saml10.equals(ref.getValueType())
-            || WSConstants.WSC_SCT.equals(ref.getValueType())) {
-            Element sa = docInfo.getAssertion();
-            String saID = null;
-            if (sa != null) {
-                saID = sa.getAttribute("AssertionID");
-            }
-            if (doDebug) {
-                log.debug("SAML token ID: " + saID);
-            }
-            String id = uri;
-            if (id.charAt(0) == '#') {
-                id = id.substring(1);
-            }
-            if (saID == null || !saID.equals(id)) {
-                if (cb != null) {
-                    //try to find a custom token
-                    WSPasswordCallback pwcb = 
-                        new WSPasswordCallback(id, WSPasswordCallback.CUSTOM_TOKEN);
-                    try {
-                        cb.handle(new Callback[]{pwcb});
-                    } catch (Exception e) {
-                        throw new WSSecurityException(
-                            WSSecurityException.FAILURE,
-                            "noPassword", 
-                            new Object[] {id}, 
-                            e
-                        );
-                    }
-                    
-                    Element assertionElem = pwcb.getCustomToken();
-                    if (assertionElem != null) {
-                        sa = (Element)doc.importNode(assertionElem, true);
-                    }
-                    else {
-                        throw new WSSecurityException(
-                            WSSecurityException.INVALID_SECURITY,
-                            "badReferenceURI",
-                            new Object[]{"uri:" + uri + ", saID: " + saID}
-                        );
-                    }
-                } else {
-                    throw new WSSecurityException(
-                        WSSecurityException.INVALID_SECURITY,
-                        "badReferenceURI",
-                        new Object[]{"uri:" + uri + ", saID: " + saID}
-                    );
-                }
-            }
-            tokElement = sa;
-        } else {
-            tokElement = WSSecurityUtil.getElementByWsuId(doc, uri);
-            
-            // In some scenarios id is used rather than wsu:Id
-            if (tokElement == null) {
-                tokElement = WSSecurityUtil.getElementByGenId(doc, uri);
-            }
-
-        }
+        
+        Element tokElement = findTokenElement(doc, docInfo, cb, uri, ref.getValueType());
+        
         if (tokElement == null) {
             throw new WSSecurityException(
                 WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
@@ -251,73 +191,92 @@
                 WSSecurityException.INVALID_SECURITY, "badReferenceURI"
             );
         }
+        
+        Element tokElement = findTokenElement(doc, docInfo, cb, value, type);
+        
+        if (tokElement == null) {
+            throw new WSSecurityException(
+                WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                "noToken",
+                new Object[]{value}
+            );
+        }
+        return tokElement;
+    }
+    
+    
+    private Element findTokenElement(
+        Document doc,
+        WSDocInfo docInfo,
+        CallbackHandler cb,
+        String uri,
+        String type
+    ) {
         Element tokElement = null;
-        String saml10 = WSConstants.WSS_SAML_NS + WSConstants.SAML_ASSERTION_ID;
-        if (saml10.equals(type)
-            || WSConstants.WSC_SCT.equals(type)) {
+        String id = uri;
+        if (id.charAt(0) == '#') {
+            id = id.substring(1);
+        }
+        //
+        // If the type is a SAMLAssertionID then find the SAML assertion - first check
+        // if it has been previously processed, else search the header for it
+        //
+        String assertionStr = WSConstants.WSS_SAML_NS + WSConstants.ASSERTION_LN;
+        if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(type)
+            || assertionStr.equals(type)) {
             Element sa = docInfo.getAssertion();
-            String saID = null;
             if (sa != null) {
-                saID = sa.getAttribute("AssertionID");
-            }
-            if (doDebug) {
-                log.debug("SAML token ID: " + saID);
+                String saID = sa.getAttribute("AssertionID");
+                if (doDebug) {
+                    log.debug("SAML token ID: " + saID);
+                }
+                if (saID.equals(id)) {
+                    tokElement = sa;
+                }
             }
-            String id = value;
-            if (id.charAt(0) == '#') {
-                id = id.substring(1);
-            }
-            if (saID == null || !saID.equals(id)) {
-                if (cb != null) {
-                    //try to find a custom token
-                    WSPasswordCallback pwcb = 
-                        new WSPasswordCallback(id, WSPasswordCallback.CUSTOM_TOKEN);
-                    try {
-                        cb.handle(new Callback[]{pwcb});
-                    } catch (Exception e) {
-                        throw new WSSecurityException(
-                            WSSecurityException.FAILURE,
-                            "noPassword", 
-                            new Object[] {id}, 
-                            e
-                        );
-                    }
-                    
-                    Element assertionElem = pwcb.getCustomToken();
-                    if (assertionElem != null) {
-                        sa = (Element)doc.importNode(assertionElem, true);
-                    }
-                    else {
-                        throw new WSSecurityException(
-                            WSSecurityException.INVALID_SECURITY,
-                            "badReferenceURI",
-                            new Object[]{"uri:" + value + ", saID: " + saID}
-                        );
-                    }
-                } else {
-                    throw new WSSecurityException(
-                        WSSecurityException.INVALID_SECURITY,
-                        "badReferenceURI",
-                        new Object[]{"uri:" + value + ", saID: " + saID}
+            if (tokElement == null) {
+                Node assertion = 
+                    WSSecurityUtil.findSAMLAssertionElementById(
+                        doc.getDocumentElement(),
+                        id
                     );
+                if (assertion != null) {
+                    tokElement = (Element)assertion;
                 }
             }
-            tokElement = sa;
-        } else {
-            tokElement = WSSecurityUtil.getElementByWsuId(doc, value);
+        }
+        
+        // 
+        // Try to find a custom token
+        //
+        if (tokElement == null && WSConstants.WSC_SCT.equals(type) && cb != null) {
+            //try to find a custom token
+            WSPasswordCallback pwcb = 
+                new WSPasswordCallback(id, WSPasswordCallback.CUSTOM_TOKEN);
+            try {
+                cb.handle(new Callback[]{pwcb});
+                Element assertionElem = pwcb.getCustomToken();
+                if (assertionElem != null) {
+                    tokElement = (Element)doc.importNode(assertionElem, true);
+                }
+            } catch (Exception e) {
+                log.debug(e.getMessage(), e);
+                // Consume this failure
+            }
+        }
+        
+        //
+        // Finally try to find the element by its Id
+        //
+        if (tokElement == null) {
+            tokElement = WSSecurityUtil.getElementByWsuId(doc, uri);
             
             // In some scenarios id is used rather than wsu:Id
             if (tokElement == null) {
-                tokElement = WSSecurityUtil.getElementByGenId(doc, value);
+                tokElement = WSSecurityUtil.getElementByGenId(doc, uri);
             }
         }
-        if (tokElement == null) {
-            throw new WSSecurityException(
-                WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
-                "noToken",
-                new Object[]{value}
-            );
-        }
+        
         return tokElement;
     }
 

Modified: webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/transform/STRTransform.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/transform/STRTransform.java?rev=769785&r1=769784&r2=769785&view=diff
==============================================================================
--- webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/transform/STRTransform.java (original)
+++ webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/transform/STRTransform.java Wed Apr 29 13:38:23 2009
@@ -238,7 +238,8 @@
         }
         // End of HACK
         catch (WSSecurityException ex) {
-            throw (new CanonicalizationException("WS Security Exception", ex));
+            log.debug(ex.getMessage(), ex);
+            throw (new CanonicalizationException("c14n.Canonicalizer.Exception", ex));
         }
     }
 

Modified: webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/util/WSSecurityUtil.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/util/WSSecurityUtil.java?rev=769785&r1=769784&r2=769785&view=diff
==============================================================================
--- webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/util/WSSecurityUtil.java (original)
+++ webservices/wss4j/branches/1_5_x-fixes/src/org/apache/ws/security/util/WSSecurityUtil.java Wed Apr 29 13:38:23 2009
@@ -256,6 +256,68 @@
         }
         return null;
     }
+    
+    
+    /**
+     * Returns the single SAMLAssertion element that contains an AssertionID/ID that
+     * matches the supplied parameter.
+     * 
+     * @param startNode Where to start the search
+     * @param value Value of the AssertionID/ID attribute
+     * @return The found element if there was exactly one match, or
+     *         <code>null</code> otherwise
+     */
+    public static Element findSAMLAssertionElementById(Node startNode, String value) {
+        Element foundElement = null;
+
+        //
+        // Replace the formerly recursive implementation with a depth-first-loop
+        // lookup
+        //
+        if (startNode == null) {
+            return null;
+        }
+        Node startParent = startNode.getParentNode();
+        Node processedNode = null;
+
+        while (startNode != null) {
+            // start node processing at this point
+            if (startNode.getNodeType() == Node.ELEMENT_NODE) {
+                Element se = (Element) startNode;
+                if ((se.hasAttribute("ID") && value.equals(se.getAttribute("ID")))
+                    || (se.hasAttribute("AssertionID") 
+                        && value.equals(se.getAttribute("AssertionID")))) {
+                    if (foundElement == null) {
+                        foundElement = se; // Continue searching to find duplicates
+                    } else {
+                        log.warn("Multiple elements with the same 'ID' attribute value!");
+                        return null;
+                    }
+                }
+            }
+
+            processedNode = startNode;
+            startNode = startNode.getFirstChild();
+
+            // no child, this node is done.
+            if (startNode == null) {
+                // close node processing, get sibling
+                startNode = processedNode.getNextSibling();
+            }
+            // no more siblings, get parent, all children
+            // of parent are processed.
+            while (startNode == null) {
+                processedNode = processedNode.getParentNode();
+                if (processedNode == startParent) {
+                    return foundElement;
+                }
+                // close parent node processing (processed node now)
+                startNode = processedNode.getNextSibling();
+            }
+        }
+        return foundElement;
+    }
+    
 
     /**
      * Returns the single element that contains an Id with value

Modified: webservices/wss4j/branches/1_5_x-fixes/test/wssec/PackageTests.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_5_x-fixes/test/wssec/PackageTests.java?rev=769785&r1=769784&r2=769785&view=diff
==============================================================================
--- webservices/wss4j/branches/1_5_x-fixes/test/wssec/PackageTests.java (original)
+++ webservices/wss4j/branches/1_5_x-fixes/test/wssec/PackageTests.java Wed Apr 29 13:38:23 2009
@@ -86,6 +86,7 @@
         suite.addTestSuite(TestWSSecurityTimestamp.class);
         suite.addTestSuite(SignatureKeyValueTest.class);
         suite.addTestSuite(TestWSSecurityResultsOrder.class);
+        suite.addTestSuite(TestWSSecurityWSS178.class);
         
         return suite;
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: wss4j-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: wss4j-dev-help@ws.apache.org