You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2011/08/12 22:14:37 UTC
svn commit: r1157233 - in /cxf/trunk:
rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/
systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/
Author: sergeyb
Date: Fri Aug 12 20:14:37 2011
New Revision: 1157233
URL: http://svn.apache.org/viewvc?rev=1157233&view=rev
Log:
[CXF-3661] Support for enveloping signatures
Modified:
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInHandler.java
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInHandler.java?rev=1157233&r1=1157232&r2=1157233&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInHandler.java (original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInHandler.java Fri Aug 12 20:14:37 2011
@@ -30,9 +30,9 @@ import javax.xml.stream.XMLStreamReader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.jaxrs.ext.RequestHandler;
@@ -133,9 +133,15 @@ public class XmlSigInHandler implements
if (!valid) {
throwFault("Signature validation failed", null);
}
-
- root.removeAttribute("ID");
- root.removeChild(sigElement);
+ if (!isEnveloping(root)) {
+ root.removeAttribute("ID");
+ root.removeChild(sigElement);
+ } else {
+ Element actualBody = getActualBody(root);
+ Document newDoc = DOMUtils.createDocument();
+ newDoc.adoptNode(actualBody);
+ root = actualBody;
+ }
message.setContent(XMLStreamReader.class,
new W3CDOMStreamReader(root));
message.setContent(InputStream.class, null);
@@ -148,10 +154,40 @@ public class XmlSigInHandler implements
return null;
}
+ private Element getActualBody(Element envelopingSigElement) {
+ Element objectNode = getNode(envelopingSigElement, Constants.SignatureSpecNS, "Object", 0);
+ if (objectNode == null) {
+ throwFault("Object envelope is not available", null);
+ }
+ NodeList list = objectNode.getChildNodes();
+ for (int i = 0; i < list.getLength(); i++) {
+ Node node = list.item(i);
+ if (node instanceof Element) {
+ objectNode.removeChild(node);
+ return (Element)node;
+ }
+ }
+ throwFault("No signed data is found", null);
+ return null;
+
+ }
+
private Element getSignatureElement(Element root) {
- NodeList list = root.getElementsByTagNameNS(Constants.SignatureSpecNS, "Signature");
- if (list != null && list.getLength() == 1) {
- return (Element)list.item(0);
+ if (isEnveloping(root)) {
+ return root;
+ }
+ return getNode(root, Constants.SignatureSpecNS, "Signature", 0);
+ }
+
+ protected boolean isEnveloping(Element root) {
+ return Constants.SignatureSpecNS.equals(root.getNamespaceURI())
+ && "Signature".equals(root.getLocalName());
+ }
+
+ private Element getNode(Element parent, String ns, String name, int index) {
+ NodeList list = parent.getElementsByTagNameNS(ns, name);
+ if (list != null && list.getLength() >= index + 1) {
+ return (Element)list.item(index);
}
return null;
}
@@ -175,16 +211,16 @@ public class XmlSigInHandler implements
} catch (XMLSecurityException ex) {
throwFault("Signature Reference is not available", ex);
}
- String rootId = root.getAttribute("ID");
- String refId = ref.getId();
- if (refId.length() == 0 && rootId.length() == 0) {
- // or fragment must be expected ?
- return;
- }
- if (refId.startsWith("#") && refId.length() > 1 && refId.substring(1).equals(rootId)) {
- return;
- } else {
- throwFault("Signature Reference ID is invalid", null);
+ if (!isEnveloping(root)) {
+ String rootId = root.getAttribute("ID");
+ String refId = ref.getURI();
+ if (refId.length() == 0 && rootId.length() == 0) {
+ // or fragment must be expected ?
+ return;
+ }
+ if (!refId.startsWith("#") || refId.length() <= 1 || !refId.substring(1).equals(rootId)) {
+ throwFault("Signature Reference ID is invalid", null);
+ }
}
Transforms transforms = null;
try {
@@ -192,20 +228,22 @@ public class XmlSigInHandler implements
} catch (XMLSecurityException ex) {
throwFault("Signature transforms can not be obtained", ex);
}
- boolean isEnveloped = false;
- for (int i = 0; i < transforms.getLength(); i++) {
- try {
- Transform tr = transforms.item(i);
- if (Transforms.TRANSFORM_ENVELOPED_SIGNATURE.equals(tr.getURI())) {
- isEnveloped = true;
- break;
+ if (!isEnveloping(root)) {
+ boolean isEnveloped = false;
+ for (int i = 0; i < transforms.getLength(); i++) {
+ try {
+ Transform tr = transforms.item(i);
+ if (Transforms.TRANSFORM_ENVELOPED_SIGNATURE.equals(tr.getURI())) {
+ isEnveloped = true;
+ break;
+ }
+ } catch (Exception ex) {
+ throwFault("Problem accessing Transform instance", ex);
}
- } catch (Exception ex) {
- throwFault("Problem accessing Transform instance", ex);
}
- }
- if (!isEnveloped) {
- throwFault("Only enveloped signatures are currently supported", null);
+ if (!isEnveloped) {
+ throwFault("Only enveloped signatures are currently supported", null);
+ }
}
}
}
Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java?rev=1157233&r1=1157232&r2=1157233&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java (original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java Fri Aug 12 20:14:37 2011
@@ -24,9 +24,12 @@ import java.util.UUID;
import java.util.logging.Logger;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.rs.security.common.CryptoLoader;
import org.apache.cxf.rs.security.common.SecurityUtils;
@@ -37,7 +40,6 @@ import org.apache.ws.security.components
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xml.security.utils.Constants;
-import org.apache.xml.security.utils.ElementProxy;
import org.opensaml.xml.signature.SignatureConstants;
@@ -45,13 +47,17 @@ public class XmlSigOutInterceptor extend
private static final Logger LOG =
LogUtils.getL7dLogger(XmlSigOutInterceptor.class);
- private boolean createReferenceId = true;
+ private boolean enveloping;
private String defaultSigAlgo = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1;
private String digestAlgo = Constants.ALGO_ID_DIGEST_SHA1;
public XmlSigOutInterceptor() {
}
+ public void setEnveloping(boolean env) {
+ this.enveloping = env;
+ }
+
public void setSignatureAlgorithm(String algo) {
defaultSigAlgo = algo;
}
@@ -60,18 +66,14 @@ public class XmlSigOutInterceptor extend
digestAlgo = algo;
}
- public void setCreateReferenceId(boolean create) {
- createReferenceId = create;
- }
protected Document processDocument(Message message, Document doc)
throws Exception {
- createEnvelopedSignature(message, doc);
- return doc;
+ return createEnvelopedSignature(message, doc);
}
// enveloping & detached sigs will be supported too
- private void createEnvelopedSignature(Message message, Document doc)
+ private Document createEnvelopedSignature(Message message, Document doc)
throws Exception {
String userNameKey = SecurityConstants.SIGNATURE_USERNAME;
@@ -89,7 +91,7 @@ public class XmlSigOutInterceptor extend
String user = SecurityUtils.getUserName(message, crypto, userNameKey);
if (StringUtils.isEmpty(user)) {
- return;
+ return null;
}
String password =
@@ -110,28 +112,60 @@ public class XmlSigOutInterceptor extend
LOG.severe(errorMessage);
throw new WSSecurityException(errorMessage, ex);
}
- //
- ElementProxy.setDefaultPrefix(Constants.SignatureSpecNS, "ds");
- String referenceId = "";
- if (createReferenceId) {
- String id = UUID.randomUUID().toString();
- referenceId = "#" + id;
- doc.getDocumentElement().setAttribute("ID", id);
- }
+ String id = UUID.randomUUID().toString();
+ String referenceId = "#" + id;
- XMLSignature sig = new XMLSignature(doc, "", sigAlgo);
- doc.getDocumentElement().appendChild(sig.getElement());
- Transforms transforms = new Transforms(doc);
- transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
- transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+ XMLSignature sig = null;
+ if (enveloping) {
+ sig = prepareEnvelopingSignature(doc, id, referenceId, sigAlgo);
+ } else {
+ sig = prepareEnvelopedSignature(doc, id, referenceId, sigAlgo);
+ }
- sig.addDocument("", transforms, digestAlgo, referenceId, null);
sig.addKeyInfo(issuerCerts[0]);
sig.addKeyInfo(issuerCerts[0].getPublicKey());
sig.sign(privateKey);
+ return sig.getElement().getOwnerDocument();
}
+ private XMLSignature prepareEnvelopingSignature(Document doc,
+ String id,
+ String referenceId,
+ String sigAlgo) throws Exception {
+ Element docEl = doc.getDocumentElement();
+ Document newDoc = DOMUtils.createDocument();
+ doc.removeChild(docEl);
+ newDoc.adoptNode(docEl);
+ Element object = newDoc.createElementNS(Constants.SignatureSpecNS, "ds:Object");
+ object.appendChild(docEl);
+ object.setAttribute("ID", id);
+
+ XMLSignature sig = new XMLSignature(newDoc, "", sigAlgo);
+ newDoc.appendChild(sig.getElement());
+ sig.getElement().appendChild(object);
+ Transforms transforms = new Transforms(newDoc);
+ transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+
+ sig.addDocument(referenceId, transforms, digestAlgo);
+ return sig;
+ }
+
+ private XMLSignature prepareEnvelopedSignature(Document doc,
+ String id,
+ String referenceURI,
+ String sigAlgo) throws Exception {
+ doc.getDocumentElement().setAttribute("ID", id);
+
+ XMLSignature sig = new XMLSignature(doc, "", sigAlgo);
+ doc.getDocumentElement().appendChild(sig.getElement());
+ Transforms transforms = new Transforms(doc);
+ transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
+ transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+
+ sig.addDocument(referenceURI, transforms, digestAlgo);
+ return sig;
+ }
}
Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java?rev=1157233&r1=1157232&r2=1157233&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java Fri Aug 12 20:14:37 2011
@@ -50,6 +50,16 @@ public class JAXRSXmlSecTest extends Abs
@Test
public void testPostBookWithEnvelopedSig() throws Exception {
String address = "https://localhost:" + PORT + "/xmlsig/bookstore/books";
+ doTestSignature(address, false);
+ }
+
+ @Test
+ public void testPostBookWithEnvelopingSig() throws Exception {
+ String address = "https://localhost:" + PORT + "/xmlsig/bookstore/books";
+ doTestSignature(address, true);
+ }
+
+ private void doTestSignature(String address, boolean enveloping) {
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
bean.setAddress(address);
@@ -65,7 +75,9 @@ public class JAXRSXmlSecTest extends Abs
properties.put("ws-security.signature.properties",
"org/apache/cxf/systest/jaxrs/security/alice.properties");
bean.setProperties(properties);
- bean.getOutInterceptors().add(new XmlSigOutInterceptor());
+ XmlSigOutInterceptor sigInterceptor = new XmlSigOutInterceptor();
+ sigInterceptor.setEnveloping(enveloping);
+ bean.getOutInterceptors().add(sigInterceptor);
WebClient wc = bean.createWebClient();
@@ -81,7 +93,6 @@ public class JAXRSXmlSecTest extends Abs
fail(ex.getMessage());
}
}
-
}
@Test