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 2012/01/17 18:05:22 UTC
svn commit: r1232483 - in /cxf/trunk:
rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/
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: Tue Jan 17 17:05:22 2012
New Revision: 1232483
URL: http://svn.apache.org/viewvc?rev=1232483&view=rev
Log:
[CXF-4038] Support for XML Signatures on the server to the client path for JAX-RS
Added:
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java (with props)
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInInterceptor.java (with props)
Modified:
cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java
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
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml
Modified: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java?rev=1232483&r1=1232482&r2=1232483&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java (original)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SamlEnvelopedInHandler.java Tue Jan 17 17:05:22 2012
@@ -40,6 +40,9 @@ public class SamlEnvelopedInHandler exte
private static final String SAML2_NS = "urn:oasis:names:tc:SAML:2.0:assertion";
private static final String SAML1_NS = "urn:oasis:names:tc:SAML:1.0:assertion";
private static final String SAML_ASSERTION = "Assertion";
+
+ private boolean bodyIsRoot;
+
public SamlEnvelopedInHandler() {
}
@@ -78,13 +81,19 @@ public class SamlEnvelopedInHandler exte
validateToken(message, samlElement);
doc.getDocumentElement().removeChild(samlElement);
- Element actualBody = getActualBody(doc.getDocumentElement());
- if (actualBody != null) {
- Document newDoc = DOMUtils.createDocument();
- newDoc.adoptNode(actualBody);
+ if (bodyIsRoot) {
message.setContent(XMLStreamReader.class,
- new W3CDOMStreamReader(actualBody));
+ new W3CDOMStreamReader(doc));
message.setContent(InputStream.class, null);
+ } else {
+ Element actualBody = getActualBody(doc.getDocumentElement());
+ if (actualBody != null) {
+ Document newDoc = DOMUtils.createDocument();
+ newDoc.adoptNode(actualBody);
+ message.setContent(XMLStreamReader.class,
+ new W3CDOMStreamReader(actualBody));
+ message.setContent(InputStream.class, null);
+ }
}
return null;
@@ -105,4 +114,8 @@ public class SamlEnvelopedInHandler exte
}
return null;
}
+
+ public void setBodyIsRoot(boolean bodyIsRoot) {
+ this.bodyIsRoot = bodyIsRoot;
+ }
}
Added: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java?rev=1232483&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java (added)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java Tue Jan 17 17:05:22 2012
@@ -0,0 +1,228 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.rs.security.xml;
+
+import java.io.InputStream;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+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.TrustValidator;
+import org.apache.cxf.staxutils.W3CDOMStreamReader;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.signature.Reference;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.transforms.Transform;
+import org.apache.xml.security.transforms.Transforms;
+import org.apache.xml.security.utils.Constants;
+
+public class AbstractXmlSigInHandler extends AbstractXmlSecInHandler {
+
+ private boolean removeSignature = true;
+ private boolean persistSignature = true;
+
+ public void setRemoveSignature(boolean remove) {
+ this.removeSignature = remove;
+ }
+
+ public void setPersistSignature(boolean persist) {
+ this.persistSignature = persist;
+ }
+
+ protected void checkSignature(Message message) {
+
+ Document doc = getDocument(message);
+ if (doc == null) {
+ return;
+ }
+
+ Element root = doc.getDocumentElement();
+ Element signatureElement = getSignatureElement(root);
+ if (signatureElement == null) {
+ throwFault("XML Signature is not available", null);
+ }
+
+ Crypto crypto = null;
+ try {
+ CryptoLoader loader = new CryptoLoader();
+ crypto = loader.getCrypto(message,
+ SecurityConstants.SIGNATURE_CRYPTO,
+ SecurityConstants.SIGNATURE_PROPERTIES);
+ if (crypto == null) {
+ crypto = loader.getCrypto(message,
+ SecurityConstants.ENCRYPT_CRYPTO,
+ SecurityConstants.ENCRYPT_PROPERTIES);
+ }
+ } catch (Exception ex) {
+ throwFault("Crypto can not be loaded", ex);
+ }
+ boolean valid = false;
+ Reference ref = null;
+ try {
+ XMLSignature signature = new XMLSignature(signatureElement, "");
+ // See also WSS4J SAMLUtil.getCredentialFromKeyInfo
+ KeyInfo keyInfo = signature.getKeyInfo();
+
+ X509Certificate cert = keyInfo.getX509Certificate();
+ if (cert != null) {
+ valid = signature.checkSignatureValue(cert);
+ } else {
+ PublicKey pk = keyInfo.getPublicKey();
+ if (pk != null) {
+ 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) {
+ message.setContent(XMLSignature.class, signature);
+ message.setContent(Element.class, signedElement);
+ }
+ } catch (Exception ex) {
+ throwFault("Signature validation failed", ex);
+ }
+ if (!valid) {
+ throwFault("Signature validation failed", null);
+ }
+ if (removeSignature) {
+ if (!isEnveloping(root)) {
+ Element signedEl = getSignedElement(root, ref);
+ signedEl.removeAttribute("ID");
+ root.removeChild(signatureElement);
+ } 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);
+
+ }
+
+ private Element getActualBody(Element envelopingSigElement) {
+ Element objectNode = getNode(envelopingSigElement, Constants.SignatureSpecNS, "Object", 0);
+ if (objectNode == null) {
+ throwFault("Object envelope is not available", null);
+ }
+ Element node = DOMUtils.getFirstElement(objectNode);
+ if (node == null) {
+ throwFault("No signed data is found", null);
+ }
+ return node;
+
+ }
+
+ private Element getSignatureElement(Element sigParentElement) {
+ if (isEnveloping(sigParentElement)) {
+ return sigParentElement;
+ }
+ return DOMUtils.getFirstChildWithName(sigParentElement, Constants.SignatureSpecNS, "Signature");
+ }
+
+ protected boolean isEnveloping(Element root) {
+ return Constants.SignatureSpecNS.equals(root.getNamespaceURI())
+ && "Signature".equals(root.getLocalName());
+ }
+
+ protected Reference getReference(XMLSignature sig) {
+ int count = sig.getSignedInfo().getLength();
+ if (count != 1) {
+ throwFault("Multiple Signature Reference are not currently supported", null);
+ }
+ try {
+ return sig.getSignedInfo().item(0);
+ } catch (XMLSecurityException ex) {
+ throwFault("Signature Reference is not available", ex);
+ }
+ return null;
+ }
+
+ protected Element validateReference(Element root, Reference ref) {
+ boolean enveloped = false;
+
+ String refId = ref.getURI();
+
+ if (!refId.startsWith("#") || refId.length() <= 1) {
+ throwFault("Only local Signature References are supported", null);
+ }
+
+ Element signedEl = getSignedElement(root, ref);
+ if (signedEl != null) {
+ enveloped = signedEl == root;
+ } else {
+ throwFault("Signature Reference ID is invalid", null);
+ }
+
+
+ Transforms transforms = null;
+ try {
+ transforms = ref.getTransforms();
+ } catch (XMLSecurityException ex) {
+ throwFault("Signature transforms can not be obtained", ex);
+ }
+ if (enveloped) {
+ 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);
+ }
+ }
+ if (!isEnveloped) {
+ throwFault("Only enveloped signatures are currently supported", null);
+ }
+ }
+ return signedEl;
+ }
+
+ private Element getSignedElement(Element root, Reference ref) {
+ String rootId = root.getAttribute("ID");
+ String expectedID = ref.getURI().substring(1);
+
+ if (!expectedID.equals(rootId)) {
+ return (Element)DOMUtils.findChildWithAtt(root, null, "ID", expectedID);
+ } else {
+ return root;
+ }
+ }
+}
Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
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=1232483&r1=1232482&r2=1232483&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 Tue Jan 17 17:05:22 2012
@@ -19,219 +19,18 @@
package org.apache.cxf.rs.security.xml;
-import java.io.InputStream;
-import java.security.PublicKey;
-import java.security.cert.X509Certificate;
-
import javax.ws.rs.core.Response;
-import javax.xml.stream.XMLStreamReader;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.jaxrs.ext.RequestHandler;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.message.Message;
-import org.apache.cxf.rs.security.common.CryptoLoader;
-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.components.crypto.Crypto;
-import org.apache.xml.security.exceptions.XMLSecurityException;
-import org.apache.xml.security.keys.KeyInfo;
-import org.apache.xml.security.signature.Reference;
-import org.apache.xml.security.signature.XMLSignature;
-import org.apache.xml.security.transforms.Transform;
-import org.apache.xml.security.transforms.Transforms;
-import org.apache.xml.security.utils.Constants;
-public class XmlSigInHandler extends AbstractXmlSecInHandler implements RequestHandler {
-
- private boolean removeSignature = true;
- private boolean persistSignature = true;
-
- public void setRemoveSignature(boolean remove) {
- this.removeSignature = remove;
- }
-
- public void setPersistSignature(boolean persist) {
- this.persistSignature = persist;
- }
+public class XmlSigInHandler extends AbstractXmlSigInHandler implements RequestHandler {
public Response handleRequest(Message message, ClassResourceInfo resourceClass) {
- Document doc = getDocument(message);
- if (doc == null) {
- return null;
- }
-
- Element root = doc.getDocumentElement();
- Element signatureElement = getSignatureElement(root);
- if (signatureElement == null) {
- throwFault("XML Signature is not available", null);
- }
-
- Crypto crypto = null;
- try {
- CryptoLoader loader = new CryptoLoader();
- crypto = loader.getCrypto(message,
- SecurityConstants.SIGNATURE_CRYPTO,
- SecurityConstants.SIGNATURE_PROPERTIES);
- if (crypto == null) {
- crypto = loader.getCrypto(message,
- SecurityConstants.ENCRYPT_CRYPTO,
- SecurityConstants.ENCRYPT_PROPERTIES);
- }
- } catch (Exception ex) {
- throwFault("Crypto can not be loaded", ex);
- }
- boolean valid = false;
- Reference ref = null;
- try {
- XMLSignature signature = new XMLSignature(signatureElement, "");
- // See also WSS4J SAMLUtil.getCredentialFromKeyInfo
- KeyInfo keyInfo = signature.getKeyInfo();
-
- X509Certificate cert = keyInfo.getX509Certificate();
- if (cert != null) {
- valid = signature.checkSignatureValue(cert);
- } else {
- PublicKey pk = keyInfo.getPublicKey();
- if (pk != null) {
- 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) {
- message.setContent(XMLSignature.class, signature);
- message.setContent(Element.class, signedElement);
- }
- } catch (Exception ex) {
- throwFault("Signature validation failed", ex);
- }
- if (!valid) {
- throwFault("Signature validation failed", null);
- }
- if (removeSignature) {
- if (!isEnveloping(root)) {
- Element signedEl = getSignedElement(root, ref);
- signedEl.removeAttribute("ID");
- root.removeChild(signatureElement);
- } 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);
-
- //TODO: If we have a SAML assertion header as well with holder-of-key or
- // sender-vouches claims then we will need to store signature or parts of it
- // to validate that saml assertion and this payload have been signed by the
- // same key
+ checkSignature(message);
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);
- }
- Element node = DOMUtils.getFirstElement(objectNode);
- if (node == null) {
- throwFault("No signed data is found", null);
- }
- return node;
-
- }
-
- private Element getSignatureElement(Element sigParentElement) {
- if (isEnveloping(sigParentElement)) {
- return sigParentElement;
- }
- return DOMUtils.getFirstChildWithName(sigParentElement, Constants.SignatureSpecNS, "Signature");
- }
-
- protected boolean isEnveloping(Element root) {
- return Constants.SignatureSpecNS.equals(root.getNamespaceURI())
- && "Signature".equals(root.getLocalName());
- }
-
- protected Reference getReference(XMLSignature sig) {
- int count = sig.getSignedInfo().getLength();
- if (count != 1) {
- throwFault("Multiple Signature Reference are not currently supported", null);
- }
- try {
- return sig.getSignedInfo().item(0);
- } catch (XMLSecurityException ex) {
- throwFault("Signature Reference is not available", ex);
- }
- return null;
- }
-
- protected Element validateReference(Element root, Reference ref) {
- boolean enveloped = false;
-
- String refId = ref.getURI();
-
- if (!refId.startsWith("#") || refId.length() <= 1) {
- throwFault("Only local Signature References are supported", null);
- }
-
- Element signedEl = getSignedElement(root, ref);
- if (signedEl != null) {
- enveloped = signedEl == root;
- } else {
- throwFault("Signature Reference ID is invalid", null);
- }
-
-
- Transforms transforms = null;
- try {
- transforms = ref.getTransforms();
- } catch (XMLSecurityException ex) {
- throwFault("Signature transforms can not be obtained", ex);
- }
- if (enveloped) {
- 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);
- }
- }
- if (!isEnveloped) {
- throwFault("Only enveloped signatures are currently supported", null);
- }
- }
- return signedEl;
- }
-
- private Element getSignedElement(Element root, Reference ref) {
- String rootId = root.getAttribute("ID");
- String expectedID = ref.getURI().substring(1);
-
- if (!expectedID.equals(rootId)) {
- return (Element)DOMUtils.findChildWithAtt(root, null, "ID", expectedID);
- } else {
- return root;
- }
- }
}
Added: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInInterceptor.java?rev=1232483&view=auto
==============================================================================
--- cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInInterceptor.java (added)
+++ cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInInterceptor.java Tue Jan 17 17:05:22 2012
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.xml;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.phase.PhaseInterceptor;
+
+public class XmlSigInInterceptor extends AbstractXmlSigInHandler implements PhaseInterceptor<Message> {
+
+ public XmlSigInInterceptor() {
+ }
+
+ public void handleFault(Message message) {
+ }
+
+ public void handleMessage(Message message) throws Fault {
+ checkSignature(message);
+ }
+
+ public Collection<PhaseInterceptor<? extends Message>> getAdditionalInterceptors() {
+ return null;
+ }
+
+ public Set<String> getAfter() {
+ return Collections.singleton(XmlEncInInterceptor.class.getName());
+ }
+
+ public Set<String> getBefore() {
+ return Collections.emptySet();
+ }
+
+ public String getId() {
+ return getClass().getName();
+ }
+
+ public String getPhase() {
+ return Phase.UNMARSHAL;
+ }
+
+
+}
Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInInterceptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigInInterceptor.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
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=1232483&r1=1232482&r2=1232483&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 Tue Jan 17 17:05:22 2012
@@ -31,7 +31,6 @@ import javax.xml.namespace.QName;
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;
@@ -48,7 +47,9 @@ import org.apache.xml.security.transform
import org.apache.xml.security.utils.Constants;
import org.opensaml.xml.signature.SignatureConstants;
-
+//TODO: Make sure that enveloped signatures can be applied to individual
+// child nodes of an envelope root element, a new property such as
+// targetElementQName will be needed
public class XmlSigOutInterceptor extends AbstractXmlSecOutInterceptor {
public static final String ENVELOPED_SIG = "enveloped";
public static final String ENVELOPING_SIG = "enveloping";
@@ -63,7 +64,7 @@ public class XmlSigOutInterceptor extend
private static final Set<String> SUPPORTED_STYLES =
new HashSet<String>(Arrays.asList(ENVELOPED_SIG, ENVELOPING_SIG, DETACHED_SIG));
- private QName envelopeQName;
+ private QName envelopeQName = DEFAULT_ENV_QNAME;
private String sigStyle = ENVELOPED_SIG;
private String defaultSigAlgo = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1;
private String digestAlgo = Constants.ALGO_ID_DIGEST_SHA1;
@@ -75,9 +76,6 @@ public class XmlSigOutInterceptor extend
if (!SUPPORTED_STYLES.contains(style)) {
throw new IllegalArgumentException("Unsupported XML Signature style");
}
- if (DETACHED_SIG.equals(style)) {
- envelopeQName = DEFAULT_ENV_QNAME;
- }
sigStyle = style;
}
@@ -99,11 +97,6 @@ public class XmlSigOutInterceptor extend
private Document createSignature(Message message, Document doc)
throws Exception {
- boolean enveloping = ENVELOPING_SIG.equals(sigStyle);
- if (enveloping && envelopeQName != null) {
- throw new IllegalStateException("Enveloping XMLSignature can not have custom envelope names");
- }
-
String userNameKey = SecurityConstants.SIGNATURE_USERNAME;
CryptoLoader loader = new CryptoLoader();
@@ -145,9 +138,9 @@ public class XmlSigOutInterceptor extend
String referenceId = "#" + id;
XMLSignature sig = null;
- if (enveloping) {
+ if (ENVELOPING_SIG.equals(sigStyle)) {
sig = prepareEnvelopingSignature(doc, id, referenceId, sigAlgo);
- } else if (envelopeQName != null) {
+ } else if (DETACHED_SIG.equals(sigStyle)) {
sig = prepareDetachedSignature(doc, id, referenceId, sigAlgo);
} else {
sig = prepareEnvelopedSignature(doc, id, referenceId, sigAlgo);
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=1232483&r1=1232482&r2=1232483&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 Tue Jan 17 17:05:22 2012
@@ -32,11 +32,13 @@ import org.apache.cxf.jaxrs.client.WebCl
import org.apache.cxf.rs.security.common.SecurityUtils;
import org.apache.cxf.rs.security.xml.XmlEncInInterceptor;
import org.apache.cxf.rs.security.xml.XmlEncOutInterceptor;
+import org.apache.cxf.rs.security.xml.XmlSigInInterceptor;
import org.apache.cxf.rs.security.xml.XmlSigOutInterceptor;
import org.apache.cxf.systest.jaxrs.security.Book;
import org.apache.cxf.systest.jaxrs.security.BookStore;
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
import org.apache.xml.security.encryption.XMLCipher;
+
import org.junit.BeforeClass;
import org.junit.Test;
@@ -126,7 +128,7 @@ public class JAXRSXmlSecTest extends Abs
sigInterceptor.setStyle(XmlSigOutInterceptor.ENVELOPING_SIG);
}
bean.getOutInterceptors().add(sigInterceptor);
-
+ bean.getInInterceptors().add(new XmlSigInInterceptor());
WebClient wc = bean.createWebClient();
try {
Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml?rev=1232483&r1=1232482&r2=1232483&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml Tue Jan 17 17:05:22 2012
@@ -67,6 +67,7 @@ under the License.
<bean id="serviceBean" class="org.apache.cxf.systest.jaxrs.security.BookStore"/>
<bean id="xmlSigHandler" class="org.apache.cxf.rs.security.xml.XmlSigInHandler"/>
+ <bean id="xmlSigOutHandler" class="org.apache.cxf.rs.security.xml.XmlSigOutInterceptor"/>
<bean id="xmlEncHandler" class="org.apache.cxf.rs.security.xml.XmlEncInHandler"/>
<bean id="xmlEncOutHandler" class="org.apache.cxf.rs.security.xml.XmlEncOutInterceptor">
<property name="symmetricEncAlgorithm" value="aes128-cbc"/>
@@ -80,7 +81,12 @@ under the License.
<jaxrs:providers>
<ref bean="xmlSigHandler"/>
</jaxrs:providers>
+ <jaxrs:outInterceptors>
+ <ref bean="xmlSigOutHandler"/>
+ </jaxrs:outInterceptors>
<jaxrs:properties>
+ <entry key="ws-security.callback-handler"
+ value="org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback"/>
<entry key="ws-security.signature.properties"
value="org/apache/cxf/systest/jaxrs/security/alice.properties"/>
</jaxrs:properties>