I have a WCF service (FooService) protected by Secure Conversation. Also have an STS (StsService) that provides tokens to clients calling FooService. The tokens are good for 15 minutes. The STS is custom-build (no Geneva). The client also has some custom WCF extensions to allow re-use of the token across several services during the lifetime of the client.
The client requests a token from the STS when "Open" on the channel to FooService is called. The STS works fine, issues the token and provides a valid RSTR back to the client. The client receives the de-serialized token (as a GenericXmlSecurityToken
object).
Problem:
When the client receives the GenericXmlSecurityToken
instance, the expiration date is NOT set correctly. In the RSTR, there is a SAML tag <saml:Conditions>
which has the valid expiration date BUT, for some reason, WCF does not seem to be parsing the tag and using the value of NotOnOrAfter
.
Here is the binding for the STS (server-side):
<binding name="stsBinding" receiveTimeout="infinite"
sendTimeout="infinite">
<security authenticationMode="SecureConversation" requireSecurityContextCancellation="true">
<localClientSettings maxClockSkew="23:59:59" />
<localServiceSettings maxClockSkew="23:59:59"
inactivityTimeout="00:02:00" />
<secureConversationBootstrap
authenticationMode="UserNameForSslNegotiated">
<localClientSettings maxClockSkew="23:59:59" />
<localServiceSettings maxClockSkew="23:59:59" />
</secureConversationBootstrap>
</security>
<binaryMessageEncoding />
Here is the client-side binding:
<binding name="stsBinding"
closeTimeout="00:02:00"
openTimeout="00:02:00"
sendTimeout="00:02:00">
<security authenticationMode="SecureConversation" requireSecurityContextCancellation="true">
<localClientSettings maxClockSkew="23:59:59" />
<localServiceSettings maxClockSkew="23:59:59"
inactivityTimeout="00:02:00" />
<secureConversationBootstrap
authenticationMode="UserNameForSslNegotiated">
<localClientSettings maxClockSkew="23:59:59" />
<localServiceSettings maxClockSkew="23:59:59" />
</secureConversationBootstrap>
</security>
<binaryMessageEncoding />
<tcpTransport maxReceivedMessageSize="2097152"
maxBufferSize="2097152" maxPendingConnections="10"
listenBacklog="10" />
</binding>
I have tried several things to get the correct expiration date to show-up... but nothings seems to work. Tried implementing a custom Serializer. Could not find any trace of <saml:Conditions>
. Also tried calling the STS directly, then providing the token back to WCF. That solution worked, calling the STS directly and de-serializing the response into a valid SecurityToken, but when it is provided back to WCF, the "Open" call on the channel times-out after 2 mintues. No error message, nothing in the trace log...
On the client-side, the token has the SAML assertion. If I look at: ((GenericXmlSecurityToken)token).TokenXml.InnerXml
, this is what I see:
<saml:Conditions
NotBefore="2009-09-01T19:36:54.669Z"
NotOnOrAfter="2009-09-01T19:41:54.669Z"
xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
</saml:Conditions>
Even tried stepping through the .NET Framework source, but cannot do that with VS 2008 SP1 on Windows 7. DOES NOT WORK! Arg!
Any ideas?