You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have spring web services deployed to remote hosts offshore that may not be using NTP services to keep their clocks synchronised resulting in potential skewing of those server system clocks. This is out of my control and causes an issue with the web service ws-security handling specifically relating to the ws-security header timestamp validation of the received message.
I attempted to increase the time to live attributes on the definition of the Wss4jSecurityInterceptor bean for example by setting these 3:
Strangely, the problem did not improve. The timestamp validation was still failing. I had increased the ttl values to 420 seconds (7 minutes) but it appeared the update had no effect.
I've done some analysis debugging the Wss4jSecurityInterceptor locally and came up with the following observations:
Default values from Wss4jSecurityInterceptor:
The TimestampValidator.validate() method is actually called twice within the Wss4jSecurityInterceptor.validateMessage() processing. Firstly in the securityEngine.processSecurityHeader() and subsequently in the verifyTimestamp() method.
It appears that the TimestampValidator.validate() method requires an initialised RequestData object passed in with the various time to live attributes propagated from the attributes of the Wss4jSecurityInterceptor.
Within the code of the Wss4jSecurityInterceptor.validateMessage() method there is an attempt to do just that via initializeValidationRequestData():
However, the initializeValidationRequestData() method doesn't propagate the attributes. Therefore the processSecurityHeader() processing ends up using the default values contained in the RequestData object being:
/** * The time in seconds between creation and expiry for a Timestamp. The default * is 300 seconds (5 minutes). */privateinttimeStampTTL = 300;
/** * The time in seconds in the future within which the Created time of an incoming * Timestamp is valid. The default is 60 seconds. */privateinttimeStampFutureTTL = 60;
This is why the overall ws-security header validation still fails because it's using these default values instead of those I had explicitly set on the Wss4jSecurityInterceptor bean.
Workaround
To address this, I extended Wss4jSecurityInterceptor and overrode the initializeValidationRequestData() method as follows:
/** * Fix: The parent calls a processSecurityHeader method on the <code>WSSecurityEngine</code> * prior to calling the verifyTimestamp as part of the validateMessage method. * The problem is that the necessary time to live attributes are not propagated * during the initializeValidationRequestData method in the parent so we need * to do it explicitly here unfortunately. */@OverrideprotectedRequestDatainitializeValidationRequestData(MessageContextmessageContext)
{
RequestDatarequestData = newRequestData();
requestData = super.initializeValidationRequestData(messageContext);
requestData.setTimeStampFutureTTL(futureTimeToLive);
requestData.setTimeStampTTL(validationTimeToLive);
requestData.setTimeStampStrict(timestampStrict);
returnrequestData;
}
This ensures that the RequestData object is correctly configured before either of the two calls to verify the timestamps. Without this, the processSecurityHeader() would fail the timestamp validation as it wasn't picking up the specified ttl values from the bean.
Potential Fix
I think the initializeValidationRequestData() method in Wss4jSecurityInterceptor class could propagate the values to the RequestData object as per my overridden method above and that would solve this bug.
Perhaps then the correctly initialised RequestData object could be passed to the verifyTimestamp() method too precluding the need for a new object to be created again inside that method.
Affects: 3.0.8
The text was updated successfully, but these errors were encountered:
Can confirm this exact same issue is still occurring using spring-boot-starter-web-services:2.6.6. So far, the workaround seems to work fine, but it did give some debugging headaches before I could pinpoint the problem.
mightybeaker opened SWS-1084 and commented
Background
I have spring web services deployed to remote hosts offshore that may not be using NTP services to keep their clocks synchronised resulting in potential skewing of those server system clocks. This is out of my control and causes an issue with the web service ws-security handling specifically relating to the ws-security header timestamp validation of the received message.
I attempted to increase the time to live attributes on the definition of the Wss4jSecurityInterceptor bean for example by setting these 3:
The full bean definition:
Problem
Strangely, the problem did not improve. The timestamp validation was still failing. I had increased the ttl values to 420 seconds (7 minutes) but it appeared the update had no effect.
I've done some analysis debugging the
Wss4jSecurityInterceptor
locally and came up with the following observations:Default values from
Wss4jSecurityInterceptor
:The
TimestampValidator.validate()
method is actually called twice within theWss4jSecurityInterceptor.validateMessage()
processing.Firstly in the
securityEngine.processSecurityHeader()
and subsequently in theverifyTimestamp()
method.It appears that the
TimestampValidator.validate()
method requires an initialisedRequestData
object passed in with the various time to live attributes propagated from the attributes of theWss4jSecurityInterceptor
.Within the code of the
Wss4jSecurityInterceptor.validateMessage()
method there is an attempt to do just that viainitializeValidationRequestData()
:However, the
initializeValidationRequestData()
method doesn't propagate the attributes. Therefore theprocessSecurityHeader()
processing ends up using the default values contained in theRequestData
object being:This is why the overall ws-security header validation still fails because it's using these default values instead of those I had explicitly set on the
Wss4jSecurityInterceptor
bean.Workaround
To address this, I extended
Wss4jSecurityInterceptor
and overrode theinitializeValidationRequestData()
method as follows:This ensures that the
RequestData
object is correctly configured before either of the two calls to verify the timestamps. Without this, theprocessSecurityHeader()
would fail the timestamp validation as it wasn't picking up the specified ttl values from the bean.Potential Fix
I think the
initializeValidationRequestData()
method inWss4jSecurityInterceptor
class could propagate the values to theRequestData
object as per my overridden method above and that would solve this bug.Perhaps then the correctly initialised
RequestData
object could be passed to theverifyTimestamp()
method too precluding the need for a new object to be created again inside that method.Affects: 3.0.8
The text was updated successfully, but these errors were encountered: