Author: coheigea
Date: Wed Dec 15 13:52:55 2010
New Revision: 1049552
URL: http://svn.apache.org/viewvc?rev=1049552&view=rev
Log:
[WSS-259] - Made it possible to pass through a DOM element via WSEncryptionPart
and WSDocInfo
- Outbound signature is much more efficient now.
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSDocInfo.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSEncryptionPart.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/EnvelopeIdResolver.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecDKSign.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignature.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignatureBase.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/util/WSSecurityUtil.java
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/EncryptionPartsTest.java
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/SignaturePartsTest.java
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSDocInfo.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSDocInfo.java?rev=1049552&r1=1049551&r2=1049552&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSDocInfo.java
(original)
+++ webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSDocInfo.java
Wed Dec 15 13:52:55 2010
@@ -45,6 +45,7 @@ public class WSDocInfo {
Document doc = null;
Crypto crypto = null;
List<Element> tokenList = null;
+ List<Element> elementList = null;
List<Processor> processors = null;
public WSDocInfo(Document doc) {
@@ -57,7 +58,7 @@ public class WSDocInfo {
}
/**
- * Clears the info data except the hash code
+ * Clears the data stored in this object
*/
public void clear() {
crypto = null;
@@ -67,12 +68,20 @@ public class WSDocInfo {
if (processors != null && processors.size() > 0) {
processors.clear();
}
+ if (elementList != null && elementList.size() > 0) {
+ elementList.clear();
+ }
tokenList = null;
processors = null;
+ elementList = null;
}
/**
+ * Store a token element for later retrieval. The token element is one of:
+ * - SecurityTokenReference element
+ * - BinarySecurityToken element
+ * - SAML Assertion element
* @param elem is the token element to store
*/
public void addTokenElement(Element elem) {
@@ -108,6 +117,42 @@ public class WSDocInfo {
}
return null;
}
+
+ /**
+ * Store a protection element for later retrieval.
+ * @param element is the protection element to store
+ */
+ public void addProtectionElement(Element element) {
+ if (elementList == null) {
+ elementList = new ArrayList<Element>();
+ }
+ elementList.add(element);
+ }
+
+ /**
+ * Get a protection element for the given (wsu) Id.
+ * @param uri is the (relative) uri of the id
+ * @return the protection element or null if nothing found
+ */
+ public Element getProtectionElement(String uri) {
+ String id = uri;
+ if (id == null) {
+ return null;
+ } else if (id.charAt(0) == '#') {
+ id = id.substring(1);
+ }
+ if (elementList != null) {
+ for (Element element : elementList) {
+ if (element != null) {
+ String cId = element.getAttributeNS(WSConstants.WSU_NS,
"Id");
+ if (id.equals(cId)) {
+ return element;
+ }
+ }
+ }
+ }
+ return null;
+ }
/**
* Get a Processor for the given Id
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSEncryptionPart.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSEncryptionPart.java?rev=1049552&r1=1049551&r2=1049552&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSEncryptionPart.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSEncryptionPart.java
Wed Dec 15 13:52:55 2010
@@ -19,6 +19,8 @@
package org.apache.ws.security;
+import org.w3c.dom.Element;
+
/**
* @author Werner Dittmann ([email protected])
*/
@@ -29,6 +31,7 @@ public class WSEncryptionPart {
private String encModifier;
private String encId;
private String id;
+ private Element element;
/**
* An xpath expression pointing to the data element
@@ -154,4 +157,20 @@ public class WSEncryptionPart {
this.xpath = xpath;
}
+ /**
+ * Set the DOM Element corresponding to this EncryptionPart
+ * @param element the DOM Element corresponding to this EncryptionPart
+ */
+ public void setElement(Element element) {
+ this.element = element;
+ }
+
+ /**
+ * Get the DOM Element corresponding to this EncryptionPart
+ * @return the DOM Element corresponding to this EncryptionPart
+ */
+ public Element getElement() {
+ return element;
+ }
+
}
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/EnvelopeIdResolver.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/EnvelopeIdResolver.java?rev=1049552&r1=1049551&r2=1049552&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/EnvelopeIdResolver.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/EnvelopeIdResolver.java
Wed Dec 15 13:52:55 2010
@@ -72,12 +72,19 @@ public class EnvelopeIdResolver extends
}
//
- // First check to see if the element that we require is a
SecurityTokenReference, or a
- // previously processed Security Token that is stored in WSDocInfo.
+ // First check to see if the element that we require is stored in as a
+ // protection element in WSDocInfo
//
String id = uriNodeValue.substring(1);
Element selectedElem = null;
if (wsDocInfo != null) {
+ selectedElem = wsDocInfo.getProtectionElement(id);
+ }
+ //
+ // Next check to see if the element that we require is a previously
processed
+ // Security Token that is stored in WSDocInfo.
+ //
+ if (selectedElem == null && wsDocInfo != null) {
selectedElem = wsDocInfo.getTokenElement(id);
}
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecDKSign.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecDKSign.java?rev=1049552&r1=1049551&r2=1049552&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecDKSign.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecDKSign.java
Wed Dec 15 13:52:55 2010
@@ -148,6 +148,7 @@ public class WSSecDKSign extends WSSecDe
secRef.setReference(refUt);
XMLStructure structure = new DOMStructure(secRef.getElement());
+ wsDocInfo.addTokenElement(secRef.getElement());
keyInfo =
keyInfoFactory.newKeyInfo(
java.util.Collections.singletonList(structure), keyInfoUri
@@ -183,7 +184,8 @@ public class WSSecDKSign extends WSSecDe
return
addReferencesToSign(
document,
- references,
+ references,
+ wsDocInfo,
signatureFactory,
secHeader,
wssConfig,
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignature.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignature.java?rev=1049552&r1=1049551&r2=1049552&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignature.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignature.java
Wed Dec 15 13:52:55 2010
@@ -335,7 +335,8 @@ public class WSSecSignature extends WSSe
return
addReferencesToSign(
document,
- references,
+ references,
+ wsDocInfo,
signatureFactory,
secHeader,
wssConfig,
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignatureBase.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignatureBase.java?rev=1049552&r1=1049551&r2=1049552&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignatureBase.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecSignatureBase.java
Wed Dec 15 13:52:55 2010
@@ -22,6 +22,7 @@ package org.apache.ws.security.message;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
import org.apache.ws.security.WSEncryptionPart;
import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityException;
@@ -57,6 +58,7 @@ public class WSSecSignatureBase extends
*
* @param doc The parent document
* @param references The list of references to sign
+ * @param wsDocInfo The WSDocInfo object to store protection elements in
* @param signatureFactory The XMLSignature object
* @param secHeader The Security Header
* @param wssConfig The WSSConfig
@@ -66,6 +68,7 @@ public class WSSecSignatureBase extends
public List<javax.xml.crypto.dsig.Reference> addReferencesToSign(
Document doc,
List<WSEncryptionPart> references,
+ WSDocInfo wsDocInfo,
XMLSignatureFactory signatureFactory,
WSSecHeader secHeader,
WSSConfig wssConfig,
@@ -89,6 +92,7 @@ public class WSSecSignatureBase extends
for (WSEncryptionPart encPart : references) {
String idToSign = encPart.getId();
String elemName = encPart.getName();
+ Element element = encPart.getElement();
//
// Set up the elements to sign. There is one reserved element
@@ -109,8 +113,12 @@ public class WSSecSignatureBase extends
} else {
TransformParameterSpec transformSpec = null;
if (wssConfig.isWsiBSPCompliant()) {
- Element toSignById =
- WSSecurityUtil.findElementById(envelope,
idToSign, false);
+ Element toSignById = element;
+ if (toSignById == null) {
+ toSignById =
+ WSSecurityUtil.findElementById(envelope,
idToSign, false);
+ wsDocInfo.addProtectionElement(toSignById);
+ }
List<String> prefixes =
getInclusivePrefixes(toSignById);
transformSpec = new ExcC14NParameterSpec(prefixes);
}
@@ -120,6 +128,9 @@ public class WSSecSignatureBase extends
transformSpec
);
}
+ if (element != null) {
+ wsDocInfo.addProtectionElement(element);
+ }
javax.xml.crypto.dsig.Reference reference =
signatureFactory.newReference(
"#" + idToSign,
@@ -131,15 +142,18 @@ public class WSSecSignatureBase extends
referenceList.add(reference);
} else {
String nmSpace = encPart.getNamespace();
- Element elementToSign =
- WSSecurityUtil.findElement(encPart, doc, false);
+ Element elementToSign = element;
if (elementToSign == null) {
- throw new WSSecurityException(
- WSSecurityException.FAILURE,
- "noEncElement",
- new Object[] {nmSpace + ", " + elemName}
- );
+ elementToSign = WSSecurityUtil.findElement(encPart,
doc, false);
+ if (elementToSign == null) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILURE,
+ "noEncElement",
+ new Object[] {nmSpace + ", " + elemName}
+ );
+ }
}
+ wsDocInfo.addProtectionElement(elementToSign);
TransformParameterSpec transformSpec = null;
if (wssConfig.isWsiBSPCompliant()) {
List<String> prefixes =
getInclusivePrefixes(elementToSign);
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/util/WSSecurityUtil.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/util/WSSecurityUtil.java?rev=1049552&r1=1049551&r2=1049552&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/util/WSSecurityUtil.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/util/WSSecurityUtil.java
Wed Dec 15 13:52:55 2010
@@ -230,11 +230,15 @@ public class WSSecurityUtil {
public static Element findElement(
WSEncryptionPart part, Document doc, boolean checkMultipleElements
) {
+ // See if the DOM Element is stored in the WSEncryptionPart first
+ if (part.getElement() != null) {
+ return part.getElement();
+ }
+
+ // Next try to find the SOAP body
String id = part.getId();
String elemName = part.getName();
String nmSpace = part.getNamespace();
-
- // Try to find the SOAP body first
Element bodyElement = WSSecurityUtil.findBodyElement(doc);
if (bodyElement != null) {
if (id != null) {
Modified:
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/EncryptionPartsTest.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/EncryptionPartsTest.java?rev=1049552&r1=1049551&r2=1049552&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/EncryptionPartsTest.java
(original)
+++
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/EncryptionPartsTest.java
Wed Dec 15 13:52:55 2010
@@ -34,6 +34,7 @@ import org.apache.ws.security.components
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.util.WSSecurityUtil;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;
@@ -318,6 +319,50 @@ public class EncryptionPartsTest extends
// expected
}
}
+
+
+ /**
+ * Test getting a DOM Element from WSEncryptionPart directly
+ */
+ @org.junit.Test
+ public void testEncryptionPartDOMElement() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
+ SOAPConstants soapConstants =
+ WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
+ WSSecEncrypt encrypt = new WSSecEncrypt();
+ encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e",
"security");
+ encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
+ // Give wrong names to make sure it's picking up the element
+ WSEncryptionPart encP =
+ new WSEncryptionPart(
+ "Incorrect Localname",
+ "Incorrect N/S",
+ "");
+ Element bodyElement = WSSecurityUtil.findBodyElement(doc);
+ assert bodyElement != null &&
"Body".equals(bodyElement.getLocalName());
+ encP.setElement(bodyElement);
+ parts.add(encP);
+ encrypt.setParts(parts);
+
+ Document encryptedDoc = encrypt.build(doc, crypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(encryptedDoc);
+ LOG.debug(outputString);
+ }
+
+ List<WSSecurityEngineResult> results = verify(encryptedDoc);
+
+ QName bodyName = new QName(soapConstants.getEnvelopeURI(), "Body");
+ WSSecurityUtil.checkAllElementsProtected(results, WSConstants.ENCR,
new QName[]{bodyName});
+ }
+
/**
* Verifies the soap envelope
Modified:
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/SignaturePartsTest.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/SignaturePartsTest.java?rev=1049552&r1=1049551&r2=1049552&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/SignaturePartsTest.java
(original)
+++
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/message/SignaturePartsTest.java
Wed Dec 15 13:52:55 2010
@@ -39,6 +39,7 @@ import org.apache.ws.security.saml.WSSec
import org.apache.ws.security.util.WSSecurityUtil;
import org.opensaml.SAMLAssertion;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import java.util.List;
import java.util.ArrayList;
@@ -339,6 +340,50 @@ public class SignaturePartsTest extends
}
}
+
+ /**
+ * Test getting a DOM Element from WSEncryptionPart directly
+ */
+ @org.junit.Test
+ public void testSignaturePartDOMElement() throws Exception {
+ WSSecSignature sign = new WSSecSignature();
+ sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+ sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
+ SOAPConstants soapConstants =
+ WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
+
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
+ // Give wrong names to make sure it's picking up the element
+ WSEncryptionPart encP =
+ new WSEncryptionPart(
+ "Incorrect Localname",
+ "Incorrect N/S",
+ "");
+ Element bodyElement = WSSecurityUtil.findBodyElement(doc);
+ assert bodyElement != null &&
"Body".equals(bodyElement.getLocalName());
+ encP.setElement(bodyElement);
+ parts.add(encP);
+ sign.setParts(parts);
+
+ Document signedDoc = sign.build(doc, crypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString =
+
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+ LOG.debug(outputString);
+ }
+
+ List<WSSecurityEngineResult> results = verify(signedDoc);
+
+ QName bodyName = new QName(soapConstants.getEnvelopeURI(), "Body");
+ WSSecurityUtil.checkAllElementsProtected(results, WSConstants.SIGN,
new QName[]{bodyName});
+ }
+
/**
* Verifies the soap envelope