Author: dkulp
Date: Wed Jun 4 07:58:47 2008
New Revision: 663146
URL: http://svn.apache.org/viewvc?rev=663146&view=rev
Log:
Merged revisions 662883 via svnmerge from
https://svn.apache.org/repos/asf/cxf/trunk
........
r662883 | dkulp | 2008-06-03 16:55:58 -0400 (Tue, 03 Jun 2008) | 3
lines
[CXF-1627] Update to latest wss4j to remove hacks needed to
workaround bugs in the older version.
Note: wss4j 1.5.4 requires the opensaml library to work at all.
Thus, that is added.
........
Modified:
cxf/branches/2.0.x-fixes/ (props changed)
cxf/branches/2.0.x-fixes/buildtools/src/main/resources/notice-
supplements.xml
cxf/branches/2.0.x-fixes/rt/ws/security/pom.xml
cxf/branches/2.0.x-fixes/rt/ws/security/src/main/java/org/apache/
cxf/ws/security/wss4j/WSS4JInInterceptor.java
cxf/branches/2.0.x-fixes/rt/ws/security/src/test/java/org/apache/
cxf/ws/security/wss4j/WSS4JInOutTest.java
Propchange: cxf/branches/2.0.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified: cxf/branches/2.0.x-fixes/buildtools/src/main/resources/
notice-supplements.xml
URL:
http://svn.apache.org/viewvc/cxf/branches/2.0.x-fixes/buildtools/src/main/resources/notice-supplements.xml?rev=663146&r1=663145&r2=663146&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- cxf/branches/2.0.x-fixes/buildtools/src/main/resources/notice-
supplements.xml (original)
+++ cxf/branches/2.0.x-fixes/buildtools/src/main/resources/notice-
supplements.xml Wed Jun 4 07:58:47 2008
@@ -162,7 +162,7 @@
</supplement>
<supplement>
<project>
- <groupId>xml-security</groupId>
+ <groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
<name>XML Security</name>
<organization>
@@ -177,6 +177,23 @@
</licenses>
</project>
</supplement>
+ <supplement>
+ <project>
+ <groupId>opensaml</groupId>
+ <artifactId>opensaml</artifactId>
+ <name>OpenSAML</name>
+ <organization>
+ <name>Internet2</name>
+ <url>http://www.opensaml.org</url>
+ </organization>
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ </license>
+ </licenses>
+ </project>
+ </supplement>
<supplement>
<project>
<groupId>xml-apis</groupId>
Modified: cxf/branches/2.0.x-fixes/rt/ws/security/pom.xml
URL:
http://svn.apache.org/viewvc/cxf/branches/2.0.x-fixes/rt/ws/security/pom.xml?rev=663146&r1=663145&r2=663146&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- cxf/branches/2.0.x-fixes/rt/ws/security/pom.xml (original)
+++ cxf/branches/2.0.x-fixes/rt/ws/security/pom.xml Wed Jun 4
07:58:47 2008
@@ -60,13 +60,29 @@
<dependency>
<groupId>org.apache.ws.security</groupId>
<artifactId>wss4j</artifactId>
- <version>1.5.2</version>
- </dependency>
- <dependency>
- <groupId>xml-security</groupId>
- <artifactId>xmlsec</artifactId>
- <version>1.3.0</version>
- <scope>runtime</scope>
+ <version>1.5.4</version>
+ <exclusions>
+ <exclusion>
+ <groupId>axis</groupId>
+ <artifactId>axis</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>axis</groupId>
+ <artifactId>axis-ant</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>bouncycastle</groupId>
+ <artifactId>bcprov-jdk15</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>xalan</groupId>
Modified: cxf/branches/2.0.x-fixes/rt/ws/security/src/main/java/org/
apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.0.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java?rev=663146&r1=663145&r2=663146&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- cxf/branches/2.0.x-fixes/rt/ws/security/src/main/java/org/
apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java (original)
+++ cxf/branches/2.0.x-fixes/rt/ws/security/src/main/java/org/
apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java Wed Jun 4
07:58:47 2008
@@ -24,8 +24,8 @@
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
-
import javax.security.auth.callback.CallbackHandler;
+import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
@@ -44,6 +44,8 @@
import org.apache.cxf.phase.Phase;
import org.apache.cxf.staxutils.StaxUtils;
import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngine;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.handler.RequestData;
@@ -61,12 +63,18 @@
public static final String TIMESTAMP_RESULT =
"wss4j.timestamp.result";
public static final String SIGNATURE_RESULT =
"wss4j.signature.result";
+ public static final String PROCESSOR_MAP =
"wss4j.processor.map";
private static final Logger LOG =
LogUtils.getL7dLogger(WSS4JInInterceptor.class);
private static final Logger TIME_LOG =
LogUtils.getL7dLogger(WSS4JInInterceptor.class,
null,
WSS4JInInterceptor.class.getName()
+
"-Time");
+
+ /**
+ *
+ */
+ private WSSecurityEngine secEngineOverride;
public WSS4JInInterceptor() {
super();
@@ -75,9 +83,15 @@
getAfter().add(SAAJInInterceptor.class.getName());
}
+ @SuppressWarnings("unchecked")
public WSS4JInInterceptor(Map<String, Object> properties) {
this();
setProperties(properties);
+ final Map<QName, String> map = + (Map<QName,
String>) properties.get(PROCESSOR_MAP);
+ if (map != null) {
+ secEngineOverride = createSecurityEngine(map);
+ }
}
@SuppressWarnings("unchecked")
@@ -127,15 +141,20 @@
* they may be used for encryption too.
*/
doReceiverAction(doAction, reqData);
-
+ Vector wsResult = null;
if (doTimeLog) {
t1 = System.currentTimeMillis();
}
try {
- wsResult =
secEngine.processSecurityHeader(doc.getSOAPPart(), actor,
cbHandler, reqData
- .getSigCrypto(), reqData.getDecCrypto());
+ wsResult =
getSecurityEngine().processSecurityHeader(
+ doc.getSOAPPart(), + actor,
+ cbHandler, +
reqData.getSigCrypto(), + reqData.getDecCrypto()
+ );
} catch (WSSecurityException ex) {
LOG.log(Level.WARNING, "", ex);
throw new SoapFault(new Message("SECURITY_FAILED",
LOG), ex, version.getSender());
@@ -157,13 +176,6 @@
if
(reqData.getWssConfig().isEnableSignatureConfirmation()) {
checkSignatureConfirmation(reqData, wsResult);
}
- - //
- // Now remove the Signature Confirmation results. This
is needed to work around the
- // wsResult.size() != actions.size() comparison below.
The real issue is to fix the
- // broken checkReceiverResults method in WSS4J.
- //
- removeSignatureConfirmationResults(wsResult);
/*
* Now we can check the certificate used to sign the
message. In the
@@ -213,11 +225,8 @@
/*
* now check the security actions: do they match, in
right order?
- *
- * Added size comparison to work around
- * https://issues.apache.org/jira/browse/WSS-70
*/
- if (wsResult.size() != actions.size() || !
checkReceiverResults(wsResult, actions)) {
+ if (!checkReceiverResults(wsResult, actions)) {
LOG.warning("Security processing failed (actions
mismatch)");
throw new SoapFault(new Message("ACTION_MISMATCH",
LOG), version.getSender());
@@ -303,18 +312,52 @@
return cbHandler;
}
- private void
removeSignatureConfirmationResults(List<Object> wsResult) {
- //
- // Now remove the Signature Confirmation results. This is
needed to work around the
- // wsResult.size() != actions.size() comparison below. The
real issue is to fix the
- // broken checkReceiverResults method in WSS4J.
- //
- for (int i = 0; i < wsResult.size(); i++) {
- Integer action = (Integer)
((WSSecurityEngineResult)wsResult.get(i))
- .get(WSSecurityEngineResult.TAG_ACTION);
- if (action != null && action.intValue() ==
WSConstants.SC) {
- wsResult.remove(i);
+ /**
+ * @return the WSSecurityEngine in use by this interceptor.
+ * This engine is defined to be the
secEngineOverride
+ * instance, if defined in this class (and
supplied through
+ * construction); otherwise, it is taken to be
the default
+ * WSSecEngine instance (currently defined in the
WSHandler
+ * base class).
+ *
+ * TODO the WSHandler base class defines secEngine to be
static, which
+ * is really bad, because the engine has mutable state on it.
+ */
+ private WSSecurityEngine
+ getSecurityEngine() {
+ if (secEngineOverride != null) {
+ return secEngineOverride;
+ }
+ return secEngine;
+ }
+
+ /**
+ * @return a freshly minted WSSecurityEngine instance,
using the
+ * (non-null) processor map, to be used to
initialize the
+ * WSSecurityEngine instance.
+ *
+ * TODO The WSS4J APIs leave something to be desired here, but
hopefully
+ * we'll clean all this up in WSS4J-2.0
+ */
+ private WSSecurityEngine
+ createSecurityEngine(
+ final Map<QName, String> map
+ ) {
+ assert map != null;
+ final WSSConfig config = WSSConfig.getNewInstance();
+ for (Map.Entry<QName, String> entry : map.entrySet()) {
+ final QName key = entry.getKey();
+ String val = entry.getValue();
+ if (val != null) {
+ val = val.trim();
+ if ("null".equals(val) || val.length() == 0) {
+ val = null;
+ }
}
+ config.setProcessor(key, val);
}
+ final WSSecurityEngine ret = new WSSecurityEngine();
+ ret.setWssConfig(config);
+ return ret;
}
}
Modified: cxf/branches/2.0.x-fixes/rt/ws/security/src/test/java/org/
apache/cxf/ws/security/wss4j/WSS4JInOutTest.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.0.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JInOutTest.java?rev=663146&r1=663145&r2=663146&view=diff
=
=
=
=
=
=
=
=
=
=====================================================================
--- cxf/branches/2.0.x-fixes/rt/ws/security/src/test/java/org/
apache/cxf/ws/security/wss4j/WSS4JInOutTest.java (original)
+++ cxf/branches/2.0.x-fixes/rt/ws/security/src/test/java/org/
apache/cxf/ws/security/wss4j/WSS4JInOutTest.java Wed Jun 4
07:58:47 2008
@@ -22,10 +22,12 @@
import java.io.ByteArrayOutputStream;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
-
+import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.MessageFactory;
@@ -41,6 +43,7 @@
import
org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.helpers.DOMUtils.NullResolver;
+import org.apache.cxf.helpers.XMLUtils;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.ExchangeImpl;
@@ -48,8 +51,11 @@
import org.apache.cxf.phase.Phase;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDataRef;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.handler.WSHandlerConstants;
+import org.apache.ws.security.handler.WSHandlerResult;
import org.junit.Test;
@@ -203,19 +209,198 @@
.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
assertNotNull(certificate);
}
+ + @Test
+ @SuppressWarnings("unchecked")
+ public void testEncryption() throws Exception {
+ Document doc = readDocument("wsse-request-clean.xml");
+
+ WSS4JOutInterceptor ohandler = new WSS4JOutInterceptor();
+ PhaseInterceptor<SoapMessage> handler =
ohandler.createEndingInterceptor();
+
+ SoapMessage msg = new SoapMessage(new MessageImpl());
+ Exchange ex = new ExchangeImpl();
+ ex.setInMessage(msg);
+ + SOAPMessage saajMsg =
MessageFactory.newInstance().createMessage();
+ SOAPPart part = saajMsg.getSOAPPart();
+ part.setContent(new DOMSource(doc));
+ saajMsg.saveChanges();
+ msg.setContent(SOAPMessage.class, saajMsg);
+ + msg.put(WSHandlerConstants.ACTION,
WSHandlerConstants.ENCRYPT);
+ msg.put(WSHandlerConstants.SIG_PROP_FILE, "META-INF/cxf/
outsecurity.properties");
+ msg.put(WSHandlerConstants.ENC_PROP_FILE, "META-INF/cxf/
outsecurity.properties");
+ msg.put(WSHandlerConstants.USER, "myalias");
+ msg.put("password", "myAliasPassword");
+
+ handler.handleMessage(msg);
+ doc = part;
+
+ assertValid("//wsse:Security", doc);
+ assertValid("//s:Body/xenc:EncryptedData", doc);
+ byte[] docbytes = getMessageBytes(doc);
+ XMLStreamReader reader =
StaxUtils.createXMLStreamReader(new ByteArrayInputStream(docbytes));
+
+ DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
+
+ dbf.setValidating(false);
+ dbf.setIgnoringComments(false);
+ dbf.setIgnoringElementContentWhitespace(true);
+ dbf.setNamespaceAware(true);
+
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ db.setEntityResolver(new NullResolver());
+ doc = StaxUtils.read(db, reader, false);
+
+ WSS4JInInterceptor inHandler = new WSS4JInInterceptor();
+
+ SoapMessage inmsg = new SoapMessage(new MessageImpl());
+ ex.setInMessage(inmsg);
+ inmsg.setContent(SOAPMessage.class, saajMsg);
+
+ inHandler.setProperty(WSHandlerConstants.ACTION,
WSHandlerConstants.ENCRYPT);
+ inHandler.setProperty(WSHandlerConstants.DEC_PROP_FILE,
"META-INF/cxf/insecurity.properties");
+ inHandler.setProperty(
+ WSHandlerConstants.PW_CALLBACK_CLASS, +
"org.apache.cxf.ws.security.wss4j.TestPwdCallback"
+ );
+
+ inHandler.handleMessage(inmsg);
+ //
+ // Check that the EncryptedData is no longer there
+ //
+ assertInvalid("//s:Body/xenc:EncryptedData",
saajMsg.getSOAPPart());
+ //
+ // There should be exactly 1 (WSS4J) HandlerResult
+ //
+ final java.util.List<WSHandlerResult> handlerResults =
+ (java.util.List<WSHandlerResult>)
inmsg.get(WSHandlerConstants.RECV_RESULTS);
+ assertNotNull(handlerResults);
+ assertSame(handlerResults.size(), 1);
+ //
+ // This should contain exactly 1 protection result
+ //
+ final java.util.List<Object> protectionResults =
+ (java.util.List<Object>)
handlerResults.get(0).getResults();
+ assertNotNull(protectionResults);
+ assertSame(protectionResults.size(), 1);
+ //
+ // This result should contain a reference to the decrypted
element,
+ // which should contain the soap:Body Qname
+ //
+ final java.util.Map<String, Object> result =
+ (java.util.Map<String, Object>)
protectionResults.get(0);
+ final java.util.List<WSDataRef> protectedElements =
+ (java.util.List<WSDataRef>) +
result.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+ assertNotNull(protectedElements);
+ assertSame(protectedElements.size(), 1);
+ assertEquals(
+ protectedElements.get(0).getName(),
+ new javax.xml.namespace.QName(
+ "http://schemas.xmlsoap.org/soap/envelope/",
+ "Body"
+ )
+ );
+ }
+ + @Test
+ public void testCustomProcessor() throws Exception {
+ Document doc = readDocument("wsse-request-clean.xml");
+
+ WSS4JOutInterceptor ohandler = new WSS4JOutInterceptor();
+ PhaseInterceptor<SoapMessage> handler =
ohandler.createEndingInterceptor();
+
+ SoapMessage msg = new SoapMessage(new MessageImpl());
+ Exchange ex = new ExchangeImpl();
+ ex.setInMessage(msg);
+ + SOAPMessage saajMsg =
MessageFactory.newInstance().createMessage();
+ SOAPPart part = saajMsg.getSOAPPart();
+ part.setContent(new DOMSource(doc));
+ saajMsg.saveChanges();
+
+ msg.setContent(SOAPMessage.class, saajMsg);
+
+ msg.put(WSHandlerConstants.ACTION,
WSHandlerConstants.SIGNATURE);
+ msg.put(WSHandlerConstants.SIG_PROP_FILE, "META-INF/cxf/
outsecurity.properties");
+ msg.put(WSHandlerConstants.USER, "myalias");
+ msg.put("password", "myAliasPassword");
+
+ handler.handleMessage(msg);
+
+ doc = part;
+ + assertValid("//wsse:Security", doc);
+ assertValid("//wsse:Security/ds:Signature", doc);
+
+ byte[] docbytes = getMessageBytes(doc);
+ XMLStreamReader reader =
StaxUtils.createXMLStreamReader(new ByteArrayInputStream(docbytes));
+
+ DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
+
+ dbf.setValidating(false);
+ dbf.setIgnoringComments(false);
+ dbf.setIgnoringElementContentWhitespace(true);
+ dbf.setNamespaceAware(true);
+
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ db.setEntityResolver(new NullResolver());
+ doc = StaxUtils.read(db, reader, false);
+
+ final Map<String, Object> properties = new HashMap<String,
Object>();
+ properties.put(
+ WSS4JInInterceptor.PROCESSOR_MAP,
+ createCustomProcessorMap()
+ );
+ WSS4JInInterceptor inHandler = new
WSS4JInInterceptor(properties);
+
+ SoapMessage inmsg = new SoapMessage(new MessageImpl());
+ ex.setInMessage(inmsg);
+ inmsg.setContent(SOAPMessage.class, saajMsg);
+
+ inHandler.setProperty(WSHandlerConstants.ACTION,
WSHandlerConstants.NO_SECURITY);
+
+ inHandler.handleMessage(inmsg);
+ + WSSecurityEngineResult result = +
(WSSecurityEngineResult)
inmsg.get(WSS4JInInterceptor.SIGNATURE_RESULT);
+ assertNull(result);
+ }
+ private byte[] getMessageBytes(Document doc) throws
Exception {
- // XMLOutputFactory factory =
XMLOutputFactory.newInstance();
ByteArrayOutputStream outputStream = new
ByteArrayOutputStream();
-
- // XMLStreamWriter byteArrayWriter =
- // factory.createXMLStreamWriter(outputStream);
XMLStreamWriter byteArrayWriter =
StaxUtils.createXMLStreamWriter(outputStream);
-
StaxUtils.writeDocument(doc, byteArrayWriter, false);
-
byteArrayWriter.flush();
return outputStream.toByteArray();
}
+
+ /**
+ * @return a processor map suitable for custom processing
of
+ * signatures (in this case, the actual processor
is
+ * null, which will cause the WSS4J runtime to do
no
+ * processing on the input)
+ */
+ private Map<QName, String>
+ createCustomProcessorMap() {
+ final Map<QName, String> ret = new HashMap<QName, String>();
+ ret.put(
+ new QName(
+ WSConstants.SIG_NS,
+ WSConstants.SIG_LN
+ ),
+ null
+ );
+ return ret;
+ }
+ + + // FOR DEBUGGING ONLY
+ /*private*/ static String serialize(Document doc) {
+ return XMLUtils.toString(doc);
+ }
}