protected override SecurityToken GetTokenCore(TimeSpan timeout) { Collection <XmlElement> reqParams = new Collection <XmlElement>(); foreach (XmlElement param in tokenRequirement.AdditionalRequestParameters) { if (param.NamespaceURI == "urn:oasis:names:tc:SAML:1.0:assertion") { reqParams.Add(param); } } ISessionCache cache = (ISessionCache)Activator.CreateInstance(clientCredentials.Cache, clientCredentials.Config); //Check the cache for existing session. String id; List <String> idSort; id = clientCredentials.ClientCertificate.Certificate.Thumbprint + ";"; id += clientCredentials.Session.Thumbprint + ";"; idSort = new List <string>(); foreach (XmlElement reqParam in reqParams) { String val; val = "{" + reqParam.GetAttribute("AttributeNamespace") + "}"; val += reqParam.GetAttribute("AttributeName"); val += "="; val += reqParam.GetElementsByTagName("AttributeValue", "urn:oasis:names:tc:SAML:1.0:assertion")[0].InnerText; val += ";"; idSort.Add(val); } idSort.Sort(); foreach (String val in idSort) { id += val; } idSort = new List <string>(); foreach (ClaimTypeRequirement req in tokenRequirement.ClaimTypeRequirements) { String val = req.ClaimType + ";"; idSort.Add(val); } idSort.Sort(); foreach (String val in idSort) { id += val; } XmlNamespaceManager nsmngr = null; DateTime notOnOrAfter = DateTime.MinValue; //Get the value from the cache XmlElement assertion = cache.Get(id); //If cache had a result, check if it is still valid if (assertion != null) { nsmngr = new XmlNamespaceManager(assertion.OwnerDocument.NameTable); nsmngr.AddNamespace("saml", "urn:oasis:names:tc:SAML:1.0:assertion"); notOnOrAfter = DateTime.Parse(assertion.SelectSingleNode("saml:Conditions/@NotOnOrAfter", nsmngr).Value, null, DateTimeStyles.RoundtripKind); if (notOnOrAfter < DateTime.UtcNow) { assertion = null; cache.Remove(id); } } //If the cache wasn't successful, create new. if (assertion == null) { //Get a new assertion token for the session StsClient target = new StsClient(tokenRequirement.IssuerBinding, tokenRequirement.IssuerAddress); target.Endpoint.Behaviors.Remove <ClientCredentials>(); target.Endpoint.Behaviors.Add(new OptClientCredentials()); target.ClientCredentials.ClientCertificate.Certificate = clientCredentials.ClientCertificate.Certificate; target.InnerChannel.OperationTimeout = timeout; assertion = target.RequestTicket("Anonymous", clientCredentials.Session, clientCredentials.Duration, reqParams, tokenRequirement.ClaimTypeRequirements); nsmngr = new XmlNamespaceManager(assertion.OwnerDocument.NameTable); nsmngr.AddNamespace("saml", "urn:oasis:names:tc:SAML:1.0:assertion"); notOnOrAfter = DateTime.Parse(assertion.SelectSingleNode("saml:Conditions/@NotOnOrAfter", nsmngr).Value, null, DateTimeStyles.RoundtripKind); cache.Add(id, assertion, notOnOrAfter); } //Get some date from the assertion token DateTime notBefore = DateTime.Parse(assertion.SelectSingleNode("saml:Conditions/@NotBefore", nsmngr).Value, null, DateTimeStyles.RoundtripKind); String assertionId = assertion.SelectSingleNode("@AssertionID", nsmngr).Value; // Create a KeyIdentifierClause for the SamlSecurityToken SamlAssertionKeyIdentifierClause samlKeyIdentifierClause = new SamlAssertionKeyIdentifierClause(assertionId); return(new GenericXmlSecurityToken(assertion, new X509SecurityToken(clientCredentials.Session), notBefore, notOnOrAfter, samlKeyIdentifierClause, samlKeyIdentifierClause, null)); }