I was attempting to set validity date information within an RSTR. Firstly, I updated the dates within the SAML assertion itself, like so
DateTime validFrom = DateTime.UtcNow;
DateTime validTo = validFrom + TimeSpan.FromDays(1);
SamlAssertion assertion = new SamlAssertion();
assertion.Conditions = new SamlConditions(validFrom, validTo);
Avid readers (!) will note that the WS-Trust schema defines the following elements for specifying the valid date range of the accompanying token:
wst:RequestSecurityTokenResponse/wst:Lifetime
wst:RequestSecurityTokenResponse/wst:Lifetime/wsu:Created
wst:RequestSecurityTokenResponse/wst:Lifetime/wsu:Expires
where wst namespace is http://schemas.xmlsoap.org/ws/2005/02/trust
and wsu namespace is
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd
It is these dates that WCF will use to determine the lifetime of a token. The trick, when setting these dates in your RSTR, is to supply them in the correct format. If you don't you'll receive a very unhelpful error message within your client, the gist of which will be 'I don't understand your date formats, but I'm not going to tell you why'. After alot of messing, and finally resorting to code decomposition, I determined that the correct format is:
time.ToUniversalTime().ToString("o");
The RSTR is modified like so (within the OnWriteBodyContents method of the RequestSecurityTokenResponse class as per the WCF samples), for completeness:
// This part tells WCF what the lifetime of the token is, without having to parse the token itself
writer.WriteStartElement("Lifetime", TrustNS);
writer.WriteElementString("Created", UtilityNS, FormatDate(validFrom));
writer.WriteElementString("Expires", UtilityNS, FormatDate(validTo));
writer.WriteEndElement();
I guess that, with hindsight, it is reasonably obvious that the time should be UTC, but as they say, hindsight is a wonderful thing.
Hopefully, this will save somebody at least a small amount of time in future!
Fluffy