Author: coheigea
Date: Fri Feb 4 17:26:31 2011
New Revision: 1067229
URL: http://svn.apache.org/viewvc?rev=1067229&view=rev
Log:
[WSS-256] - Throw an exception on processing multiple security headers with the
same actor.
Added:
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/misc/SecurityHeaderTest.java
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecHeader.java
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/util/WSSecurityUtil.java
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java?rev=1067229&r1=1067228&r2=1067229&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java
Fri Feb 4 17:26:31 2011
@@ -1103,7 +1103,7 @@ public abstract class WSHandler {
* @param timeToLive
* the limit on the receivers' side, that the timestamp is
validated against
* @return true if the timestamp is before (now-timeToLive), false
otherwise
- * @Deprecated TTL validation is now done by default in the
TimestampProcessor
+ * @deprecated TTL validation is now done by default in the
TimestampProcessor
* @throws WSSecurityException
*/
protected boolean verifyTimestamp(Timestamp timestamp, int timeToLive)
throws WSSecurityException {
Modified:
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecHeader.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecHeader.java?rev=1067229&r1=1067228&r2=1067229&view=diff
==============================================================================
---
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecHeader.java
(original)
+++
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecHeader.java
Fri Feb 4 17:26:31 2011
@@ -19,6 +19,7 @@
package org.apache.ws.security.message;
import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.util.WSSecurityUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -103,7 +104,7 @@ public class WSSecHeader {
* @return true if empty or if there is no security header
* false if non empty security header
*/
- public boolean isEmpty(Document doc) {
+ public boolean isEmpty(Document doc) throws WSSecurityException {
if (securityHeader == null) {
securityHeader =
WSSecurityUtil.findWsseSecurityHeaderBlock(
@@ -127,7 +128,7 @@ public class WSSecHeader {
* @param doc A SOAP envelope as <code>Document</code>
* @return A <code>wsse:Security</code> element
*/
- public Element insertSecurityHeader(Document doc) {
+ public Element insertSecurityHeader(Document doc) throws
WSSecurityException {
//
// If there is already a security header in this instance just return
it
//
@@ -172,7 +173,7 @@ public class WSSecHeader {
return securityHeader;
}
- public void removeSecurityHeader(Document doc) {
+ public void removeSecurityHeader(Document doc) throws WSSecurityException {
if (securityHeader == null) {
securityHeader =
WSSecurityUtil.findWsseSecurityHeaderBlock(
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=1067229&r1=1067228&r2=1067229&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
Fri Feb 4 17:26:31 2011
@@ -82,7 +82,7 @@ public class WSSecurityUtil {
* @return the <code>wsse:Security</code> element or <code>null</code>
* if not such element found
*/
- public static Element getSecurityHeader(Document doc, String actor) {
+ public static Element getSecurityHeader(Document doc, String actor) throws
WSSecurityException {
String soapNamespace =
WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
Element soapHeaderElement =
getDirectChildElement(
@@ -98,27 +98,38 @@ public class WSSecurityUtil {
if (WSConstants.URI_SOAP12_ENV.equals(soapNamespace)) {
actorLocal = WSConstants.ATTR_ROLE;
}
+
//
- // get all wsse:Security nodes
+ // Iterate through the security headers
//
- List<Node> securityHeaderList =
- getDirectChildElements(
- soapHeaderElement,
- WSConstants.WSSE_LN,
- WSConstants.WSSE_NS
- );
- if (securityHeaderList == null) {
- return null;
- }
- for (int i = 0; i < securityHeaderList.size(); i++) {
- Element elem = (Element) securityHeaderList.get(i);
- Attr attr = elem.getAttributeNodeNS(soapNamespace, actorLocal);
- String hActor = (attr != null) ? attr.getValue() : null;
- if (WSSecurityUtil.isActorEqual(actor, hActor)) {
- return elem;
+ Element foundSecurityHeader = null;
+ for (
+ Node currentChild = soapHeaderElement.getFirstChild();
+ currentChild != null;
+ currentChild = currentChild.getNextSibling()
+ ) {
+ if (Node.ELEMENT_NODE == currentChild.getNodeType()
+ && WSConstants.WSSE_LN.equals(currentChild.getLocalName())
+ && WSConstants.WSSE_NS.equals(currentChild.getNamespaceURI()))
{
+
+ Element elem = (Element)currentChild;
+ Attr attr = elem.getAttributeNodeNS(soapNamespace, actorLocal);
+ String hActor = (attr != null) ? attr.getValue() : null;
+
+ if (WSSecurityUtil.isActorEqual(actor, hActor)) {
+ if (foundSecurityHeader != null) {
+ if (log.isDebugEnabled()) {
+ log.debug(
+ "Two or more security headers have the same
actor name: " + actor
+ );
+ }
+ throw new
WSSecurityException(WSSecurityException.INVALID_SECURITY);
+ }
+ foundSecurityHeader = elem;
+ }
}
}
- return null;
+ return foundSecurityHeader;
}
@@ -642,7 +653,7 @@ public class WSSecurityUtil {
Document doc,
Element envelope,
boolean doCreate
- ) {
+ ) throws WSSecurityException {
return findWsseSecurityHeaderBlock(doc, envelope, null, doCreate);
}
@@ -660,7 +671,7 @@ public class WSSecurityUtil {
Element envelope,
String actor,
boolean doCreate
- ) {
+ ) throws WSSecurityException {
Element wsseSecurity = getSecurityHeader(doc, actor);
if (wsseSecurity != null) {
return wsseSecurity;
Added:
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/misc/SecurityHeaderTest.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/misc/SecurityHeaderTest.java?rev=1067229&view=auto
==============================================================================
---
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/misc/SecurityHeaderTest.java
(added)
+++
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/misc/SecurityHeaderTest.java
Fri Feb 4 17:26:31 2011
@@ -0,0 +1,127 @@
+/**
+ * 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.ws.security.misc;
+
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.common.SOAPUtil;
+import org.w3c.dom.Document;
+
+/**
+ * This tests how security headers are parsed and processed.
+ */
+public class SecurityHeaderTest extends org.junit.Assert {
+ private static final String DUPLICATE_NULL_ACTOR_MSG =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<SOAP-ENV:Envelope
xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
+ + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
+ + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ + "<SOAP-ENV:Header>"
+ + "<wsse:Security SOAP-ENV:mustUnderstand=\"1\" "
+ +
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">"
+ + "</wsse:Security>"
+ + "<wsse:Security SOAP-ENV:mustUnderstand=\"1\" "
+ +
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">"
+ + "</wsse:Security>"
+ + "</SOAP-ENV:Header>"
+ + "<SOAP-ENV:Body>"
+ + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">"
+ + "<value xmlns=\"\">15</value>" + "</add>"
+ + "</SOAP-ENV:Body>\r\n \r\n" + "</SOAP-ENV:Envelope>";
+ private static final String DUPLICATE_ACTOR_MSG =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<SOAP-ENV:Envelope
xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
+ + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
+ + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ + "<SOAP-ENV:Header>"
+ + "<wsse:Security SOAP-ENV:actor=\"user\"
SOAP-ENV:mustUnderstand=\"1\" "
+ +
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">"
+ + "</wsse:Security>"
+ + "<wsse:Security SOAP-ENV:actor=\"user\"
SOAP-ENV:mustUnderstand=\"1\" "
+ +
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">"
+ + "</wsse:Security>"
+ + "</SOAP-ENV:Header>"
+ + "<SOAP-ENV:Body>"
+ + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">"
+ + "<value xmlns=\"\">15</value>" + "</add>"
+ + "</SOAP-ENV:Body>\r\n \r\n" + "</SOAP-ENV:Envelope>";
+ private static final String TWO_ACTOR_MSG =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<SOAP-ENV:Envelope
xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
+ + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
+ + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ + "<SOAP-ENV:Header>"
+ + "<wsse:Security SOAP-ENV:mustUnderstand=\"1\" "
+ +
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">"
+ + "</wsse:Security>"
+ + "<wsse:Security SOAP-ENV:actor=\"user\"
SOAP-ENV:mustUnderstand=\"1\" "
+ +
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">"
+ + "</wsse:Security>"
+ + "</SOAP-ENV:Header>"
+ + "<SOAP-ENV:Body>"
+ + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">"
+ + "<value xmlns=\"\">15</value>" + "</add>"
+ + "</SOAP-ENV:Body>\r\n \r\n" + "</SOAP-ENV:Envelope>";
+
+ private WSSecurityEngine secEngine = new WSSecurityEngine();
+
+ /**
+ * Test for processing multiple security headers with the same (null) actor
+ */
+ @org.junit.Test
+ public void testDuplicateNullActor() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(DUPLICATE_NULL_ACTOR_MSG);
+ try {
+ secEngine.processSecurityHeader(doc, null, null, null);
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ /**
+ * Test for processing multiple security headers with the same actor
+ */
+ @org.junit.Test
+ public void testDuplicateActor() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(DUPLICATE_ACTOR_MSG);
+ try {
+ secEngine.processSecurityHeader(doc, "user", null, null);
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ try {
+ secEngine.processSecurityHeader(doc, "otheruser", null, null);
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+ }
+
+ /**
+ * Test for processing multiple security headers with different actors
+ */
+ @org.junit.Test
+ public void testTwoActors() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(TWO_ACTOR_MSG);
+ secEngine.processSecurityHeader(doc, null, null, null);
+
+ secEngine.processSecurityHeader(doc, "user", null, null);
+ }
+}