Author: coheigea
Date: Wed Feb 27 20:00:38 2013
New Revision: 1450942
URL: http://svn.apache.org/r1450942
Log:
[WSS-427] - Add support for processing UsernameToken Created Dates
- For StaX.
Modified:
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSSecurityProperties.java
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/UsernameTokenInputHandler.java
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/TimestampValidatorImpl.java
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/UsernameTokenValidatorImpl.java
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/UsernameTokenTest.java
Modified:
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSSecurityProperties.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSSecurityProperties.java?rev=1450942&r1=1450941&r2=1450942&view=diff
==============================================================================
---
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSSecurityProperties.java
(original)
+++
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/ext/WSSSecurityProperties.java
Wed Feb 27 20:00:38 2013
@@ -54,6 +54,8 @@ public class WSSSecurityProperties exten
private Integer timestampTTL = 300;
private Integer timeStampFutureTTL = 60;
private boolean strictTimestampCheck = true;
+ private Integer utTTL = 300;
+ private Integer utFutureTTL = 60;
/**
* This variable controls whether types other than PasswordDigest or
PasswordText
@@ -112,6 +114,8 @@ public class WSSSecurityProperties exten
this.validators.putAll(wssSecurityProperties.validators);
this.timestampTTL = wssSecurityProperties.timestampTTL;
this.timeStampFutureTTL = wssSecurityProperties.timeStampFutureTTL;
+ this.utTTL = wssSecurityProperties.utTTL;
+ this.utFutureTTL = wssSecurityProperties.utFutureTTL;
this.strictTimestampCheck = wssSecurityProperties.strictTimestampCheck;
this.handleCustomPasswordTypes =
wssSecurityProperties.handleCustomPasswordTypes;
this.usernameTokenPasswordType =
wssSecurityProperties.usernameTokenPasswordType;
@@ -609,4 +613,20 @@ public class WSSSecurityProperties exten
public void setTimeStampFutureTTL(Integer timeStampFutureTTL) {
this.timeStampFutureTTL = timeStampFutureTTL;
}
+
+ public Integer getUtTTL() {
+ return utTTL;
+ }
+
+ public void setUtTTL(Integer utTTL) {
+ this.utTTL = utTTL;
+ }
+
+ public Integer getUtFutureTTL() {
+ return utFutureTTL;
+ }
+
+ public void setUtFutureTTL(Integer utFutureTTL) {
+ this.utFutureTTL = utFutureTTL;
+ }
}
Modified:
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/UsernameTokenInputHandler.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/UsernameTokenInputHandler.java?rev=1450942&r1=1450941&r2=1450942&view=diff
==============================================================================
---
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/UsernameTokenInputHandler.java
(original)
+++
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/UsernameTokenInputHandler.java
Wed Feb 27 20:00:38 2013
@@ -24,8 +24,10 @@ import org.apache.jcs.engine.ElementAttr
import org.apache.wss4j.binding.wss10.EncodedString;
import org.apache.wss4j.binding.wss10.PasswordString;
import org.apache.wss4j.binding.wss10.UsernameTokenType;
+import org.apache.wss4j.binding.wsu10.AttributedDateTime;
import org.apache.wss4j.common.bsp.BSPRule;
import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.DateUtil;
import org.apache.wss4j.stax.ext.WSSConstants;
import org.apache.wss4j.stax.ext.WSSSecurityProperties;
import org.apache.wss4j.stax.ext.WSSecurityContext;
@@ -39,8 +41,11 @@ import org.apache.xml.security.stax.ext.
import org.apache.xml.security.stax.impl.util.IDGenerator;
import javax.xml.bind.JAXBElement;
+import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;
+
+import java.util.Date;
import java.util.Deque;
import java.util.List;
@@ -103,7 +108,10 @@ public class UsernameTokenInputHandler e
final WSSecurityContext wsSecurityContext = (WSSecurityContext)
inputProcessorChain.getSecurityContext();
final WSSSecurityProperties wssSecurityProperties =
(WSSSecurityProperties) securityProperties;
final List<QName> elementPath = getElementPath(eventQueue);
-
+
+ // Verify Created
+ verifyCreated(wssSecurityProperties, usernameTokenType);
+
final TokenContext tokenContext = new
TokenContext(wssSecurityProperties, wsSecurityContext, xmlSecEvents,
elementPath);
UsernameTokenValidator usernameTokenValidator =
@@ -196,4 +204,32 @@ public class UsernameTokenInputHandler e
}
}
+
+ private void verifyCreated(
+ WSSSecurityProperties wssSecurityProperties,
+ UsernameTokenType usernameTokenType
+ ) throws WSSecurityException {
+ // Verify Created
+ int ttl = wssSecurityProperties.getUtTTL();
+ int futureTTL = wssSecurityProperties.getUtFutureTTL();
+
+ final AttributedDateTime attributedDateTimeCreated =
+ XMLSecurityUtils.getQNameType(usernameTokenType.getAny(),
WSSConstants.TAG_wsu_Created);
+
+ if (attributedDateTimeCreated != null) {
+ // Parse the Date
+ XMLGregorianCalendar created;
+ try {
+ created =
WSSConstants.datatypeFactory.newXMLGregorianCalendar(attributedDateTimeCreated.getValue());
+ } catch (IllegalArgumentException e) {
+ throw new
WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e);
+ }
+ Date createdDate = created.toGregorianCalendar().getTime();
+
+ // Validate whether the security semantics have expired
+ if (!DateUtil.verifyCreated(createdDate, ttl, futureTTL)) {
+ throw new
WSSecurityException(WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
+ }
+ }
+ }
}
Modified:
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/TimestampValidatorImpl.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/TimestampValidatorImpl.java?rev=1450942&r1=1450941&r2=1450942&view=diff
==============================================================================
---
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/TimestampValidatorImpl.java
(original)
+++
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/TimestampValidatorImpl.java
Wed Feb 27 20:00:38 2013
@@ -22,6 +22,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wss4j.binding.wsu10.TimestampType;
import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.DateUtil;
import org.apache.wss4j.stax.ext.WSSConstants;
import javax.xml.datatype.XMLGregorianCalendar;
@@ -81,7 +82,7 @@ public class TimestampValidatorImpl impl
"The security semantics of the message have expired");
}
- if (createdDate != null && !verifyCreated(createdDate, ttl,
futureTTL)) {
+ if (createdDate != null && !DateUtil.verifyCreated(createdDate,
ttl, futureTTL)) {
log.debug("Time now: " +
WSSConstants.datatypeFactory.newXMLGregorianCalendar(new
GregorianCalendar()).toXMLFormat());
throw new
WSSecurityException(WSSecurityException.ErrorCode.MESSAGE_EXPIRED,
"invalidTimestamp",
"The security semantics of the message have expired");
@@ -92,38 +93,4 @@ public class TimestampValidatorImpl impl
}
}
- /**
- * Return true if the "Created" value is before the current time minus the
timeToLive
- * argument, and if the Created value is not "in the future".
- */
- private boolean verifyCreated(
- Date createdDate,
- int timeToLive,
- int futureTimeToLive
- ) {
- Date validCreation = new Date();
- long currentTime = validCreation.getTime();
- if (futureTimeToLive > 0) {
- validCreation.setTime(currentTime + ((long)futureTimeToLive *
1000L));
- }
- // Check to see if the created time is in the future
- if (createdDate.after(validCreation)) {
- log.debug("Validation of Timestamp: The message was created in the
future!");
- return false;
- }
-
- // Calculate the time that is allowed for the message to travel
- currentTime -= ((long)timeToLive * 1000L);
- validCreation.setTime(currentTime);
-
- // Validate the time it took the message to travel
- if (createdDate.before(validCreation)) {
- log.debug("Validation of Timestamp: The message was created too
long ago");
- return false;
- }
-
- log.debug("Validation of Timestamp: Everything is ok");
-
- return true;
- }
}
Modified:
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/UsernameTokenValidatorImpl.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/UsernameTokenValidatorImpl.java?rev=1450942&r1=1450941&r2=1450942&view=diff
==============================================================================
---
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/UsernameTokenValidatorImpl.java
(original)
+++
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/UsernameTokenValidatorImpl.java
Wed Feb 27 20:00:38 2013
@@ -32,10 +32,6 @@ import org.apache.wss4j.stax.impl.securi
import org.apache.xml.security.stax.ext.XMLSecurityUtils;
import
org.apache.xml.security.stax.impl.securityToken.AbstractInboundSecurityToken;
-import javax.xml.datatype.XMLGregorianCalendar;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-
/**
* @author $Author$
* @version $Revision$ $Date$
@@ -61,7 +57,6 @@ public class UsernameTokenValidatorImpl
||
Boolean.parseBoolean((String)tokenContext.getWsSecurityContext().get(WSSConstants.PROP_ALLOW_USERNAMETOKEN_NOPASSWORD));
final byte[] nonceVal;
- final String created;
WSSConstants.UsernameTokenPasswordType usernameTokenPasswordType =
WSSConstants.UsernameTokenPasswordType.PASSWORD_NONE;
if (passwordType != null && passwordType.getType() != null) {
@@ -78,6 +73,12 @@ public class UsernameTokenValidatorImpl
final AttributedDateTime attributedDateTimeCreated =
XMLSecurityUtils.getQNameType(usernameTokenType.getAny(),
WSSConstants.TAG_wsu_Created);
+ final String created;
+ if (attributedDateTimeCreated != null) {
+ created = attributedDateTimeCreated.getValue();
+ } else {
+ created = null;
+ }
if (usernameTokenPasswordType ==
WSSConstants.UsernameTokenPasswordType.PASSWORD_DIGEST) {
if (encodedNonce == null || attributedDateTimeCreated == null) {
@@ -89,30 +90,12 @@ public class UsernameTokenValidatorImpl
}
nonceVal = Base64.decodeBase64(encodedNonce.getValue());
- created = attributedDateTimeCreated.getValue();
-
- XMLGregorianCalendar xmlGregorianCalendar;
- try {
- xmlGregorianCalendar =
attributedDateTimeCreated.getAsXMLGregorianCalendar();
- } catch (IllegalArgumentException e) {
- throw new
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
- }
- GregorianCalendar createdCal =
xmlGregorianCalendar.toGregorianCalendar();
- GregorianCalendar now = new GregorianCalendar();
- if (createdCal.after(now)) {
- throw new
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
- }
- now.add(Calendar.MINUTE, 5);
- if (createdCal.after(now)) {
- throw new
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
- }
verifyDigestPassword(username.getValue(), passwordType, nonceVal,
created, tokenContext);
} else if ((usernameTokenPasswordType ==
WSSConstants.UsernameTokenPasswordType.PASSWORD_TEXT)
|| (passwordType != null && passwordType.getValue() != null
&& usernameTokenPasswordType ==
WSSConstants.UsernameTokenPasswordType.PASSWORD_NONE)) {
nonceVal = null;
- created = null;
verifyPlaintextPassword(username.getValue(), passwordType,
tokenContext);
} else if (passwordType != null && passwordType.getValue() != null) {
@@ -120,7 +103,6 @@ public class UsernameTokenValidatorImpl
throw new
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
}
nonceVal = null;
- created = null;
verifyCustomPassword(username.getValue(), passwordType,
tokenContext);
} else {
@@ -128,7 +110,6 @@ public class UsernameTokenValidatorImpl
throw new
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
}
nonceVal = null;
- created = null;
}
final String password;
Modified:
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/UsernameTokenTest.java
URL:
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/UsernameTokenTest.java?rev=1450942&r1=1450941&r2=1450942&view=diff
==============================================================================
---
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/UsernameTokenTest.java
(original)
+++
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/UsernameTokenTest.java
Wed Feb 27 20:00:38 2013
@@ -35,6 +35,7 @@ import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
+import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
@@ -44,6 +45,8 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
import java.util.Properties;
/**
@@ -220,15 +223,24 @@ public class UsernameTokenTest extends A
@Test
public void testReusedNonce() throws Exception {
+
+ XMLGregorianCalendar created =
+ WSSConstants.datatypeFactory.newXMLGregorianCalendar(new
GregorianCalendar());
+ String createdString = created.toXMLFormat();
+ String digest =
+ org.apache.wss4j.dom.message.token.UsernameToken.doPasswordDigest(
+ "Ex2YESUvsa1qne1m6TM8XA==", createdString, "default"
+ );
+
String req = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<env:Envelope
xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
" <env:Header>" +
" <wsse:Security
xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"
xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"
env:mustUnderstand=\"1\">" +
" <wsse:UsernameToken wsu:Id=\"UsernameToken-1\">" +
" <wsse:Username>transmitter</wsse:Username>" +
- " <wsse:Password
Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">HJuU+E+LKyZyC7k1BX7GF7kyACY=</wsse:Password>"
+
+ " <wsse:Password
Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">"
+ digest + "</wsse:Password>" +
" <wsse:Nonce
EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">Ex2YESUvsa1qne1m6TM8XA==</wsse:Nonce>"
+
- "
<wsu:Created>2011-05-21T17:14:42.545Z</wsu:Created>" +
+ " <wsu:Created>" + createdString +
"</wsu:Created>" +
" </wsse:UsernameToken>" +
" </wsse:Security>\n" +
" </env:Header>\n" +
@@ -251,7 +263,144 @@ public class UsernameTokenTest extends A
Assert.assertEquals(((WSSecurityException)
e.getCause()).getFaultCode(), WSSecurityException.FAILED_AUTHENTICATION);
}
}
+
+ /**
+ * This is a test for processing an "old" UsernameToken, i.e. one with a
"Created" element that is
+ * out of date
+ */
+ @Test
+ public void testOldUsernameToken() throws Exception {
+
+ GregorianCalendar createdCalendar = new GregorianCalendar();
+ createdCalendar.add(Calendar.SECOND, -301);
+ XMLGregorianCalendar created =
+
WSSConstants.datatypeFactory.newXMLGregorianCalendar(createdCalendar);
+ String createdString = created.toXMLFormat();
+
+ String digest =
+ org.apache.wss4j.dom.message.token.UsernameToken.doPasswordDigest(
+ "Ex2YEKVvsa1qne1m6TM8XA==", createdString, "default"
+ );
+
+ String req = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+ "<env:Envelope
xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
+ " <env:Header>" +
+ " <wsse:Security
xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"
xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"
env:mustUnderstand=\"1\">" +
+ " <wsse:UsernameToken wsu:Id=\"UsernameToken-1\">" +
+ " <wsse:Username>transmitter</wsse:Username>" +
+ " <wsse:Password
Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">"
+ digest + "</wsse:Password>" +
+ " <wsse:Nonce
EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">Ex2YEKVvsa1qne1m6TM8XA==</wsse:Nonce>"
+
+ " <wsu:Created>" + createdString +
"</wsu:Created>" +
+ " </wsse:UsernameToken>" +
+ " </wsse:Security>\n" +
+ " </env:Header>\n" +
+ " <env:Body>\n" +
+ " </env:Body>\n" +
+ "</env:Envelope>";
+ WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+ securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+ InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
+
+ try {
+ XMLStreamReader xmlStreamReader =
+
wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new
ByteArrayInputStream(req.getBytes())));
+ StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(),
xmlStreamReader);
+ Assert.fail("Expected XMLStreamException");
+ } catch (XMLStreamException e) {
+ Assert.assertEquals(e.getMessage(),
"org.apache.wss4j.common.ext.WSSecurityException: The message has expired");
+ Assert.assertEquals(((WSSecurityException)
e.getCause()).getFaultCode(), WSSecurityException.MESSAGE_EXPIRED);
+ }
+ }
+
+ /**
+ * This is a test for processing a UsernameToken where the "Created"
element is in the (near)
+ * future. It should be accepted by default when it is created 30 seconds
in the future.
+ */
+ @Test
+ public void testNearFutureCreated() throws Exception {
+ GregorianCalendar createdCalendar = new GregorianCalendar();
+ createdCalendar.add(Calendar.SECOND, 30);
+ XMLGregorianCalendar created =
+
WSSConstants.datatypeFactory.newXMLGregorianCalendar(createdCalendar);
+ String createdString = created.toXMLFormat();
+
+ String digest =
+ org.apache.wss4j.dom.message.token.UsernameToken.doPasswordDigest(
+ "Ex2YEKVvSa1qne1m6TM8XA==", createdString, "default"
+ );
+
+ String req = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+ "<env:Envelope
xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
+ " <env:Header>" +
+ " <wsse:Security
xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"
xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"
env:mustUnderstand=\"1\">" +
+ " <wsse:UsernameToken wsu:Id=\"UsernameToken-1\">" +
+ " <wsse:Username>transmitter</wsse:Username>" +
+ " <wsse:Password
Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">"
+ digest + "</wsse:Password>" +
+ " <wsse:Nonce
EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">Ex2YEKVvSa1qne1m6TM8XA==</wsse:Nonce>"
+
+ " <wsu:Created>" + createdString +
"</wsu:Created>" +
+ " </wsse:UsernameToken>" +
+ " </wsse:Security>\n" +
+ " </env:Header>\n" +
+ " <env:Body>\n" +
+ " </env:Body>\n" +
+ "</env:Envelope>";
+
+ WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+ securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+ InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
+ XMLStreamReader xmlStreamReader =
wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new
ByteArrayInputStream(req.getBytes())));
+ StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(),
xmlStreamReader);
+ }
+
+ /**
+ * This is a test for processing a UsernameToken where the "Created"
element is in the future.
+ * A UsernameToken that is 120 seconds in the future should be rejected by
default.
+ */
+ @Test
+ public void testFutureCreated() throws Exception {
+ GregorianCalendar createdCalendar = new GregorianCalendar();
+ createdCalendar.add(Calendar.SECOND, 120);
+ XMLGregorianCalendar created =
+
WSSConstants.datatypeFactory.newXMLGregorianCalendar(createdCalendar);
+ String createdString = created.toXMLFormat();
+
+ String digest =
+ org.apache.wss4j.dom.message.token.UsernameToken.doPasswordDigest(
+ "Ex2YEKVvsa1Qne1m6TM8XA==", createdString, "default"
+ );
+
+ String req = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+ "<env:Envelope
xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
+ " <env:Header>" +
+ " <wsse:Security
xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"
xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"
env:mustUnderstand=\"1\">" +
+ " <wsse:UsernameToken wsu:Id=\"UsernameToken-1\">" +
+ " <wsse:Username>transmitter</wsse:Username>" +
+ " <wsse:Password
Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">"
+ digest + "</wsse:Password>" +
+ " <wsse:Nonce
EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">Ex2YEKVvsa1Qne1m6TM8XA==</wsse:Nonce>"
+
+ " <wsu:Created>" + createdString +
"</wsu:Created>" +
+ " </wsse:UsernameToken>" +
+ " </wsse:Security>\n" +
+ " </env:Header>\n" +
+ " <env:Body>\n" +
+ " </env:Body>\n" +
+ "</env:Envelope>";
+
+ WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+ securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+ InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
+
+ try {
+ XMLStreamReader xmlStreamReader =
+
wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new
ByteArrayInputStream(req.getBytes())));
+ StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(),
xmlStreamReader);
+ Assert.fail("Expected XMLStreamException");
+ } catch (XMLStreamException e) {
+ Assert.assertEquals(e.getMessage(),
"org.apache.wss4j.common.ext.WSSecurityException: The message has expired");
+ Assert.assertEquals(((WSSecurityException)
e.getCause()).getFaultCode(), WSSecurityException.MESSAGE_EXPIRED);
+ }
+ }
+
@Test
public void testDefaultConfigurationOutbound() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();