SWS-193 - added skipValidationIfNoHeaderPresent
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.ws.soap.security;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
@@ -29,6 +30,7 @@ import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.EndpointExceptionResolver;
|
||||
import org.springframework.ws.soap.SoapBody;
|
||||
import org.springframework.ws.soap.SoapFault;
|
||||
import org.springframework.ws.soap.SoapHeader;
|
||||
import org.springframework.ws.soap.SoapHeaderElement;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.server.SoapEndpointInterceptor;
|
||||
@@ -61,6 +63,8 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
|
||||
private boolean secureRequest = true;
|
||||
|
||||
private boolean validateResponse = true;
|
||||
|
||||
private boolean skipValidationIfNoHeaderPresent = false;
|
||||
|
||||
private EndpointExceptionResolver exceptionResolver;
|
||||
|
||||
@@ -89,11 +93,17 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
|
||||
this.exceptionResolver = exceptionResolver;
|
||||
}
|
||||
|
||||
/** Allows skipping validation if no security header is present. */
|
||||
public void setSkipValidationIfNoHeaderPresent(
|
||||
boolean skipValidationIfNoHeaderPresent) {
|
||||
this.skipValidationIfNoHeaderPresent = skipValidationIfNoHeaderPresent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Server-side
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
* Validates a server-side incoming request. Delegates to {@link #validateMessage(org.springframework.ws.soap.SoapMessage,org.springframework.ws.context.MessageContext)}
|
||||
* if the {@link #setValidateRequest(boolean) validateRequest} property is <code>true</code>.
|
||||
*
|
||||
@@ -106,6 +116,9 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
|
||||
public final boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
|
||||
if (validateRequest) {
|
||||
Assert.isInstanceOf(SoapMessage.class, messageContext.getRequest());
|
||||
if(skipValidationIfNoHeaderPresent && !isSecurityHeaderPresent((SoapMessage) messageContext.getRequest())){
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
validateMessage((SoapMessage) messageContext.getRequest(), messageContext);
|
||||
return true;
|
||||
@@ -122,7 +135,7 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Secures a server-side outgoing response. Delegates to {@link #secureMessage(org.springframework.ws.soap.SoapMessage,org.springframework.ws.context.MessageContext)}
|
||||
* if the {@link #setSecureResponse(boolean) secureResponse} property is <code>true</code>.
|
||||
*
|
||||
@@ -213,6 +226,9 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
|
||||
if (validateResponse) {
|
||||
Assert.isTrue(messageContext.hasResponse(), "MessageContext contains no response");
|
||||
Assert.isInstanceOf(SoapMessage.class, messageContext.getResponse());
|
||||
if(skipValidationIfNoHeaderPresent && !isSecurityHeaderPresent((SoapMessage) messageContext.getRequest())){
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
validateMessage((SoapMessage) messageContext.getResponse(), messageContext);
|
||||
return true;
|
||||
@@ -320,4 +336,22 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
|
||||
throws WsSecuritySecurementException;
|
||||
|
||||
protected abstract void cleanUp();
|
||||
|
||||
/**
|
||||
* Iterates over header elements and returns true if WS-Security header is found.
|
||||
*/
|
||||
private boolean isSecurityHeaderPresent(SoapMessage message) {
|
||||
SoapHeader soapHeader = message.getSoapHeader();
|
||||
if(soapHeader == null){
|
||||
return false;
|
||||
}
|
||||
Iterator<SoapHeaderElement> elements = soapHeader.examineAllHeaderElements();
|
||||
while(elements.hasNext()){
|
||||
SoapHeaderElement e = elements.next();
|
||||
if(e.getName().equals(WS_SECURITY_NAME)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,15 @@
|
||||
|
||||
package org.springframework.ws.soap.security.wss4j;
|
||||
|
||||
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;
|
||||
@@ -28,11 +32,6 @@ import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.security.WsSecurityValidationException;
|
||||
import org.springframework.ws.soap.security.wss4j.callback.SimplePasswordValidationCallbackHandler;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public abstract class Wss4jMessageInterceptorHeaderTestCase extends Wss4jTestCase {
|
||||
|
||||
private Wss4jSecurityInterceptor interceptor;
|
||||
@@ -50,7 +49,7 @@ public abstract class Wss4jMessageInterceptorHeaderTestCase extends Wss4jTestCas
|
||||
interceptor.setValidationCallbackHandler(callbackHandler);
|
||||
interceptor.afterPropertiesSet();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testValidateUsernameTokenPlainText() throws Exception {
|
||||
SoapMessage message = loadSoap11Message("usernameTokenPlainTextWithHeaders-soap.xml");
|
||||
@@ -76,17 +75,20 @@ public abstract class Wss4jMessageInterceptorHeaderTestCase extends Wss4jTestCas
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=WsSecurityValidationException.class)
|
||||
public void testEmptySecurityHeader() throws Exception {
|
||||
SoapMessage message = loadSoap11Message("emptySecurityHeader-soap.xml");
|
||||
MessageContext messageContext = new DefaultMessageContext(message, getSoap11MessageFactory());
|
||||
try {
|
||||
interceptor.validateMessage(message, messageContext);
|
||||
fail("validation must fail for an empty security header.");
|
||||
}
|
||||
catch (WsSecurityValidationException e) {
|
||||
// expected
|
||||
}
|
||||
interceptor.validateMessage(message, messageContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipValidationOnEmptyHeader() throws Exception {
|
||||
SoapMessage message = loadSoap11Message("noSecurityHeader-soap.xml");
|
||||
MessageContext messageContext = new DefaultMessageContext(message, getSoap11MessageFactory());
|
||||
interceptor.setSkipValidationIfNoHeaderPresent(true);
|
||||
boolean result = interceptor.handleRequest(messageContext, null);
|
||||
assertTrue("handeRequest result must be true", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<SOAP-ENV:Body>
|
||||
<tru:StockSymbol xmlns:tru="http://fabrikam123.com/payloads">QQQ</tru:StockSymbol>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>
|
||||
Reference in New Issue
Block a user