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/01/20 19:51:24 UTC
svn commit: r1234064 - in
/cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml:
AbstractXmlSigInHandler.java XmlSigOutInterceptor.java
Author: coheigea
Date: Fri Jan 20 18:51:24 2012
New Revision: 1234064
URL: http://svn.apache.org/viewvc?rev=1234064&view=rev
Log:
Updating RS-Security code to work with Santuario 1.5
Modified:
cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java
cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java
Modified: cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java?rev=1234064&r1=1234063&r2=1234064&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java (original)
+++ cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java Fri Jan 20 18:51:24 2012
@@ -27,6 +27,7 @@ import javax.xml.stream.XMLStreamReader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.message.Message;
@@ -34,6 +35,7 @@ import org.apache.cxf.rs.security.common
import org.apache.cxf.rs.security.common.TrustValidator;
import org.apache.cxf.staxutils.W3CDOMStreamReader;
import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.ws.security.WSConstants;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.keys.KeyInfo;
@@ -86,7 +88,15 @@ public class AbstractXmlSigInHandler ext
boolean valid = false;
Reference ref = null;
try {
- XMLSignature signature = new XMLSignature(signatureElement, "");
+ XMLSignature signature = new XMLSignature(signatureElement, "");
+ // TODO re-enable this line once we pick up xmlsec 1.5.0
+ // XMLSignature signature = new XMLSignature(signatureElement, "", true);
+ ref = getReference(signature);
+ Element signedElement = validateReference(root, ref);
+ if (signedElement.hasAttributeNS(null, "ID")) {
+ signedElement.setIdAttributeNS(null, "ID", true);
+ }
+
// See also WSS4J SAMLUtil.getCredentialFromKeyInfo
KeyInfo keyInfo = signature.getKeyInfo();
@@ -99,14 +109,11 @@ public class AbstractXmlSigInHandler ext
valid = signature.checkSignatureValue(pk);
}
}
- // is this call redundant given that signature.checkSignatureValue uses References ?
- ref = getReference(signature);
- Element signedElement = validateReference(root, ref);
// validate trust
new TrustValidator().validateTrust(crypto, cert, keyInfo.getPublicKey());
- if (persistSignature) {
+ if (valid && persistSignature) {
message.setContent(XMLSignature.class, signature);
message.setContent(Element.class, signedElement);
}
@@ -220,9 +227,84 @@ public class AbstractXmlSigInHandler ext
String expectedID = ref.getURI().substring(1);
if (!expectedID.equals(rootId)) {
- return (Element)DOMUtils.findChildWithAtt(root, null, "ID", expectedID);
+ return findElementById(root, expectedID, true);
} else {
return root;
}
}
+
+ /**
+ * Returns the single element that contains an Id with value
+ * <code>uri</code> and <code>namespace</code>. The Id can be either a wsu:Id or an Id
+ * with no namespace. This is a replacement for a XPath Id lookup with the given namespace.
+ * It's somewhat faster than XPath, and we do not deal with prefixes, just with the real
+ * namespace URI
+ *
+ * If checkMultipleElements is true and there are multiple elements, we log a
+ * warning and return null as this can be used to get around the signature checking.
+ *
+ * @param startNode Where to start the search
+ * @param value Value of the Id attribute
+ * @param checkMultipleElements If true then go through the entire tree and return
+ * null if there are multiple elements with the same Id
+ * @return The found element if there was exactly one match, or
+ * <code>null</code> otherwise
+ */
+ private static Element findElementById(
+ Node startNode, String value, boolean checkMultipleElements
+ ) {
+ //
+ // Replace the formerly recursive implementation with a depth-first-loop lookup
+ //
+ Node startParent = startNode.getParentNode();
+ Node processedNode = null;
+ Element foundElement = null;
+ String id = value;
+
+ while (startNode != null) {
+ // start node processing at this point
+ if (startNode.getNodeType() == Node.ELEMENT_NODE) {
+ Element se = (Element) startNode;
+ // Try the wsu:Id first
+ String attributeNS = se.getAttributeNS(WSConstants.WSU_NS, "Id");
+ if ("".equals(attributeNS) || !id.equals(attributeNS)) {
+ attributeNS = se.getAttributeNS(null, "Id");
+ }
+ if ("".equals(attributeNS) || !id.equals(attributeNS)) {
+ attributeNS = se.getAttributeNS(null, "ID");
+ }
+ if (!"".equals(attributeNS) && id.equals(attributeNS)) {
+ if (!checkMultipleElements) {
+ return se;
+ } else if (foundElement == null) {
+ foundElement = se; // Continue searching to find duplicates
+ } else {
+ // 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;
+ }
+
}
Modified: cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java?rev=1234064&r1=1234063&r2=1234064&view=diff
==============================================================================
--- cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java (original)
+++ cxf/branches/2.5.x-fixes/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java Fri Jan 20 18:51:24 2012
@@ -163,7 +163,8 @@ public class XmlSigOutInterceptor extend
newDoc.adoptNode(docEl);
Element object = newDoc.createElementNS(Constants.SignatureSpecNS, "ds:Object");
object.appendChild(docEl);
- object.setAttribute("ID", id);
+ docEl.setAttributeNS(null, "ID", id);
+ docEl.setIdAttributeNS(null, "ID", true);
XMLSignature sig = new XMLSignature(newDoc, "", sigAlgo);
newDoc.appendChild(sig.getElement());
@@ -184,7 +185,8 @@ public class XmlSigOutInterceptor extend
Document newDoc = DOMUtils.createDocument();
doc.removeChild(docEl);
newDoc.adoptNode(docEl);
- docEl.setAttribute("ID", id);
+ docEl.setAttributeNS(null, "ID", id);
+ docEl.setIdAttributeNS(null, "ID", true);
Element root = newDoc.createElementNS(envelopeQName.getNamespaceURI(),
envelopeQName.getPrefix() + ":" + envelopeQName.getLocalPart());
@@ -205,7 +207,8 @@ public class XmlSigOutInterceptor extend
String id,
String referenceURI,
String sigAlgo) throws Exception {
- doc.getDocumentElement().setAttribute("ID", id);
+ doc.getDocumentElement().setAttributeNS(null, "ID", id);
+ doc.getDocumentElement().setIdAttributeNS(null, "ID", true);
XMLSignature sig = new XMLSignature(doc, "", sigAlgo);
doc.getDocumentElement().appendChild(sig.getElement());