SWS-577 - Wss4jSecurityInterceptor ignores Timestamp timeToLive property when creating Timestamp element
This commit is contained in:
@@ -121,7 +121,9 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
|
||||
|
||||
private boolean enableSignatureConfirmation;
|
||||
|
||||
private int timeToLive = 300;
|
||||
private int validationTimeToLive = 300;
|
||||
|
||||
private int securementTimeToLive = 300;
|
||||
|
||||
private final Wss4jHandler handler = new Wss4jHandler();
|
||||
|
||||
@@ -346,12 +348,27 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
|
||||
this.securementUsername = securementUsername;
|
||||
}
|
||||
|
||||
/** Sets the server-side time to live */
|
||||
public void setTimeToLive(int timeToLive) {
|
||||
if (timeToLive <= 0) {
|
||||
/** Sets the time to live on the outgoing message */
|
||||
public void setSecurementTimeToLive(int securementTimeToLive) {
|
||||
if (securementTimeToLive <= 0) {
|
||||
throw new IllegalArgumentException("timeToLive must be positive");
|
||||
}
|
||||
this.timeToLive = timeToLive;
|
||||
this.securementTimeToLive = securementTimeToLive;
|
||||
}
|
||||
|
||||
/** Sets the server-side time to live */
|
||||
public void setValidationTimeToLive(int validationTimeToLive) {
|
||||
if (validationTimeToLive <= 0) {
|
||||
throw new IllegalArgumentException("timeToLive must be positive");
|
||||
}
|
||||
this.validationTimeToLive = validationTimeToLive;
|
||||
}
|
||||
|
||||
/** Sets the server-side time to live
|
||||
* @deprecated Use {@link #setValidationTimeToLive(int)} instead.
|
||||
* */
|
||||
public void setTimeToLive(int timeToLive) {
|
||||
setValidationTimeToLive(timeToLive);
|
||||
}
|
||||
|
||||
/** Sets the validation actions to be executed by the interceptor. */
|
||||
@@ -497,6 +514,9 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
|
||||
else {
|
||||
requestData.setUsername(securementUsername);
|
||||
}
|
||||
|
||||
requestData.setTimeToLive(securementTimeToLive);
|
||||
|
||||
return requestData;
|
||||
}
|
||||
|
||||
@@ -596,12 +616,11 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
|
||||
if (actionResult != null) {
|
||||
Timestamp timestamp = (Timestamp) actionResult.get(WSSecurityEngineResult.TAG_TIMESTAMP);
|
||||
if (timestamp != null && timestampStrict) {
|
||||
if (!handler.verifyTimestamp(timestamp, timeToLive)) {
|
||||
if (!handler.verifyTimestamp(timestamp, validationTimeToLive)) {
|
||||
throw new Wss4jSecurityValidationException("Invalid timestamp : " + timestamp.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void processPrincipal(Vector results) {
|
||||
|
||||
@@ -17,12 +17,21 @@
|
||||
package org.springframework.ws.soap.security.wss4j;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import org.springframework.ws.context.DefaultMessageContext;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.soap.SoapMessage;
|
||||
import org.springframework.ws.soap.security.WsSecurityValidationException;
|
||||
import org.springframework.xml.transform.StringResult;
|
||||
|
||||
public abstract class Wss4jMessageInterceptorTimestampTestCase extends Wss4jTestCase {
|
||||
|
||||
@@ -50,36 +59,41 @@ public abstract class Wss4jMessageInterceptorTimestampTestCase extends Wss4jTest
|
||||
getDocument(message));
|
||||
}
|
||||
|
||||
public void testValidateTimestampWithTtl() throws Exception {
|
||||
Wss4jSecurityInterceptor interceptor = new Wss4jSecurityInterceptor() {
|
||||
public void setTimeToLive(int t) {
|
||||
try {
|
||||
Field ttl = Wss4jSecurityInterceptor.class
|
||||
.getDeclaredField("timeToLive");
|
||||
ttl.setAccessible(true);
|
||||
ttl.set(this, new Integer(t));
|
||||
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
public void testValidateTimestampWithExpiredTtl() throws Exception {
|
||||
Wss4jSecurityInterceptor interceptor = new Wss4jSecurityInterceptor();
|
||||
interceptor.setValidationActions("Timestamp");
|
||||
interceptor.setTimeToLive(-10);
|
||||
interceptor.setTimestampStrict(true);
|
||||
interceptor.afterPropertiesSet();
|
||||
SoapMessage message = getMessageWithTimestamp();
|
||||
SoapMessage message = loadMessage("expiredTimestamp-soap.xml");
|
||||
MessageContext context = new DefaultMessageContext(message, getMessageFactory());
|
||||
|
||||
try {
|
||||
interceptor.validateMessage(message, context);
|
||||
fail();
|
||||
}
|
||||
catch (Wss4jSecurityValidationException ex) {
|
||||
catch (WsSecurityValidationException e) {
|
||||
// expected
|
||||
return;
|
||||
}
|
||||
fail("Time to live validation failed");
|
||||
}
|
||||
|
||||
public void testSecureTimestampWithCustomTtl() throws Exception {
|
||||
int ttlInSeconds = 1;
|
||||
Wss4jSecurityInterceptor interceptor = new Wss4jSecurityInterceptor();
|
||||
interceptor.setSecurementActions("Timestamp");
|
||||
interceptor.setTimestampStrict(true);
|
||||
interceptor.setSecurementTimeToLive(ttlInSeconds);
|
||||
interceptor.afterPropertiesSet();
|
||||
SoapMessage message = loadMessage("empty-soap.xml");
|
||||
MessageContext context = new DefaultMessageContext(message, getMessageFactory());
|
||||
interceptor.secureMessage(message, context);
|
||||
|
||||
String created = xpathTemplate.evaluateAsString("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsu:Timestamp/wsu:Created/text()",
|
||||
message.getEnvelope().getSource());
|
||||
String expires = xpathTemplate.evaluateAsString("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsu:Timestamp/wsu:Expires/text()",
|
||||
message.getEnvelope().getSource());
|
||||
|
||||
DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SS'Z'");
|
||||
|
||||
long actualTtl = format.parse(expires).getTime() - format.parse(created).getTime();
|
||||
assertEquals("invalid ttl", 1000 * ttlInSeconds, actualTtl);
|
||||
}
|
||||
|
||||
private SoapMessage getMessageWithTimestamp() throws Exception {
|
||||
|
||||
@@ -65,7 +65,6 @@ public abstract class Wss4jTestCase extends TestCase {
|
||||
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
|
||||
namespaces.setProperty("ds", "http://www.w3.org/2000/09/xmldsig#");
|
||||
namespaces.setProperty("xenc", "http://www.w3.org/2001/04/xmlenc#");
|
||||
// namespaces.put("wsse11", "http://docs.oasis-open.org/wss/2005/xx/oasis-2005xx-wss-wssecurity-secext-1.1.xsd");
|
||||
namespaces.setProperty("wsse11", "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd");
|
||||
namespaces.setProperty("echo", "http://www.springframework.org/spring-ws/samples/echo");
|
||||
namespaces.setProperty("wsu",
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<SOAP-ENV:Header>
|
||||
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" SOAP-ENV:mustUnderstand="1">
|
||||
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-27">
|
||||
<wsu:Created>2009-12-25T15:43:22.687Z</wsu:Created>
|
||||
<wsu:Expires>2009-12-25T15:48:22.687Z</wsu:Expires>
|
||||
</wsu:Timestamp>
|
||||
</wsse:Security>
|
||||
</SOAP-ENV:Header>
|
||||
<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