diff --git a/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j/Wss4jSecurityInterceptor.java b/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j/Wss4jSecurityInterceptor.java
index 63e2044d..440e79e1 100755
--- a/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j/Wss4jSecurityInterceptor.java
+++ b/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j/Wss4jSecurityInterceptor.java
@@ -82,6 +82,7 @@ import org.springframework.ws.soap.security.wss4j.callback.UsernameTokenPrincipa
*
* @author Tareq Abed Rabbo
* @author Arjen Poutsma
+ * @author Greg Turnquist
* @see Apache WSS4J
* @since 1.5.0
*/
@@ -137,6 +138,9 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
private boolean securementUseDerivedKey;
+ // To maintain same behavior as default, this flag is set to true
+ private boolean removeSecurityHeader = true;
+
public void setSecurementActions(String securementActions) {
this.securementActions = securementActions;
securementActionsVector = new ArrayList();
@@ -502,7 +506,15 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
this.samlIssuer = samlIssuer;
}
- @Override
+ public boolean getRemoveSecurityHeader() {
+ return removeSecurityHeader;
+ }
+
+ public void setRemoveSecurityHeader(boolean removeSecurityHeader) {
+ this.removeSecurityHeader = removeSecurityHeader;
+ }
+
+ @Override
public void afterPropertiesSet() throws Exception {
Assert.isTrue(validationActions != null || securementActions != null,
"validationActions or securementActions are required");
@@ -628,7 +640,9 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
soapMessage.setDocument(envelopeAsDocument);
- soapMessage.getEnvelope().getHeader().removeHeaderElement(WS_SECURITY_NAME);
+ if (this.getRemoveSecurityHeader()) {
+ soapMessage.getEnvelope().getHeader().removeHeaderElement(WS_SECURITY_NAME);
+ }
}
/**
diff --git a/spring-ws-security/src/test/java/org/springframework/ws/soap/security/wss4j/Wss4jMessageInterceptorHeaderTestCase.java b/spring-ws-security/src/test/java/org/springframework/ws/soap/security/wss4j/Wss4jMessageInterceptorHeaderTestCase.java
index ccf51a75..a3c3ecd0 100755
--- a/spring-ws-security/src/test/java/org/springframework/ws/soap/security/wss4j/Wss4jMessageInterceptorHeaderTestCase.java
+++ b/spring-ws-security/src/test/java/org/springframework/ws/soap/security/wss4j/Wss4jMessageInterceptorHeaderTestCase.java
@@ -21,10 +21,10 @@ import static org.junit.Assert.*;
import java.io.ByteArrayOutputStream;
import java.util.Iterator;
import java.util.Properties;
-
import javax.xml.namespace.QName;
import org.junit.Test;
+
import org.springframework.ws.context.DefaultMessageContext;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.SoapHeaderElement;
@@ -32,9 +32,15 @@ import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.security.WsSecurityValidationException;
import org.springframework.ws.soap.security.wss4j.callback.SimplePasswordValidationCallbackHandler;
+/**
+ * @author Arjen Poutsma
+ * @author Tareq Abedrabbo
+ * @author Greg Turnquist
+ */
public abstract class Wss4jMessageInterceptorHeaderTestCase extends Wss4jTestCase {
private Wss4jSecurityInterceptor interceptor;
+ private Wss4jSecurityInterceptor interceptorThatKeepsSecurityHeader;
@Override
protected void onSetup() throws Exception {
@@ -48,6 +54,14 @@ public abstract class Wss4jMessageInterceptorHeaderTestCase extends Wss4jTestCas
callbackHandler.setUsers(users);
interceptor.setValidationCallbackHandler(callbackHandler);
interceptor.afterPropertiesSet();
+
+ interceptorThatKeepsSecurityHeader = new Wss4jSecurityInterceptor();
+ interceptorThatKeepsSecurityHeader.setValidateRequest(true);
+ interceptorThatKeepsSecurityHeader.setSecureResponse(true);
+ interceptorThatKeepsSecurityHeader.setValidationActions("UsernameToken");
+ interceptorThatKeepsSecurityHeader.setValidationCallbackHandler(callbackHandler);
+ interceptorThatKeepsSecurityHeader.setRemoveSecurityHeader(false);
+ interceptorThatKeepsSecurityHeader.afterPropertiesSet();
}
@Test
@@ -75,6 +89,31 @@ public abstract class Wss4jMessageInterceptorHeaderTestCase extends Wss4jTestCas
}
+ @Test
+ public void testValidateUsernameTokenPlainTextButKeepSecurityHeader() throws Exception {
+ SoapMessage message = loadSoap11Message("usernameTokenPlainTextWithHeaders-soap.xml");
+ MessageContext messageContext = new DefaultMessageContext(message, getSoap11MessageFactory());
+ interceptorThatKeepsSecurityHeader.validateMessage(message, messageContext);
+ Object result = getMessage(message);
+ assertNotNull("No result returned", result);
+
+ boolean foundSecurityHeader = false;
+ for (Iterator i = message.getEnvelope().getHeader().examineAllHeaderElements(); i.hasNext();) {
+ SoapHeaderElement element = i.next();
+ QName name = element.getName();
+ if (name.getNamespaceURI()
+ .equals("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")) {
+ foundSecurityHeader = true;
+ }
+
+ }
+ assertTrue(foundSecurityHeader);
+
+ assertXpathExists("header1 not found", "/SOAP-ENV:Envelope/SOAP-ENV:Header/header1", getDocument(message));
+ assertXpathExists("header2 not found", "/SOAP-ENV:Envelope/SOAP-ENV:Header/header2", getDocument(message));
+
+ }
+
@Test(expected=WsSecurityValidationException.class)
public void testEmptySecurityHeader() throws Exception {
SoapMessage message = loadSoap11Message("emptySecurityHeader-soap.xml");