/// <summary> /// Serializes the given token to the XmlWriter. /// </summary> /// <param name="writer">XmlWriter to which the token needs to be serialized</param> /// <param name="token">The SecurityToken to be serialized.</param> /// <exception cref="ArgumentNullException">The input argument 'writer' is null.</exception> /// <exception cref="InvalidOperationException">The input argument 'token' is either null or not of type /// SessionSecurityToken.</exception> public override void WriteToken(XmlWriter writer, SecurityToken token) { if (writer == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer"); } if (token == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token"); } SessionSecurityToken sessionToken = token as SessionSecurityToken; if (sessionToken == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4046, token, TokenType))); } string ns, elementName, contextIdElementName, instance; if (sessionToken.SecureConversationVersion == WSSecureConversationFeb2005Constants.NamespaceUri) { ns = WSSecureConversationFeb2005Constants.Namespace; elementName = WSSecureConversationFeb2005Constants.ElementNames.Name; contextIdElementName = WSSecureConversationFeb2005Constants.ElementNames.Identifier; instance = WSSecureConversationFeb2005Constants.ElementNames.Instance; } else if (sessionToken.SecureConversationVersion == WSSecureConversation13Constants.NamespaceUri) { ns = WSSecureConversation13Constants.Namespace; elementName = WSSecureConversation13Constants.ElementNames.Name; contextIdElementName = WSSecureConversation13Constants.ElementNames.Identifier; instance = WSSecureConversation13Constants.ElementNames.Instance; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ID4050))); } XmlDictionaryWriter dicWriter; SessionDictionary dictionary = SessionDictionary.Instance; if (writer is XmlDictionaryWriter) { dicWriter = (XmlDictionaryWriter)writer; } else { dicWriter = XmlDictionaryWriter.CreateDictionaryWriter(writer); } dicWriter.WriteStartElement(elementName, ns); if (sessionToken.Id != null) { dicWriter.WriteAttributeString(WSUtilityConstants.Attributes.IdAttribute, WSUtilityConstants.NamespaceURI, sessionToken.Id); } dicWriter.WriteElementString(contextIdElementName, ns, sessionToken.ContextId.ToString()); if (sessionToken.KeyGeneration != null) { dicWriter.WriteStartElement(instance, ns); dicWriter.WriteValue(sessionToken.KeyGeneration); dicWriter.WriteEndElement(); } if (!sessionToken.IsReferenceMode) { dicWriter.WriteStartElement(CookieElementName, CookieNamespace); byte[] cookie; using (MemoryStream ms = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, token); cookie = ms.ToArray(); } cookie = ApplyTransforms(cookie, true); dicWriter.WriteBase64(cookie, 0, cookie.Length); dicWriter.WriteEndElement(); } dicWriter.WriteEndElement(); dicWriter.Flush(); }
/// <summary> /// Reads the SessionSecurityToken from the given reader. /// </summary> /// <param name="reader">XmlReader over the SessionSecurityToken.</param> /// <param name="tokenResolver">SecurityTokenResolver that can used to resolve SessionSecurityToken.</param> /// <returns>An instance of <see cref="SessionSecurityToken"/>.</returns> /// <exception cref="ArgumentNullException">The input argument 'reader' is null.</exception> /// <exception cref="SecurityTokenException">The 'reader' is not positioned at a SessionSecurityToken /// or the SessionSecurityToken cannot be read.</exception> public override SecurityToken ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver) { if (reader == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader"); } if (tokenResolver == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenResolver"); } byte[] encodedCookie = null; SysUniqueId contextId = null; SysUniqueId keyGeneration = null; string ns = null; string identifier = null; string instance = null; SecurityToken securityContextToken = null; SessionDictionary dictionary = SessionDictionary.Instance; XmlDictionaryReader dicReader = XmlDictionaryReader.CreateDictionaryReader(reader); if (dicReader.IsStartElement(WSSecureConversationFeb2005Constants.ElementNames.Name, WSSecureConversationFeb2005Constants.Namespace)) { ns = WSSecureConversationFeb2005Constants.Namespace; identifier = WSSecureConversationFeb2005Constants.ElementNames.Identifier; instance = WSSecureConversationFeb2005Constants.ElementNames.Instance; } else if (dicReader.IsStartElement(WSSecureConversation13Constants.ElementNames.Name, WSSecureConversation13Constants.Namespace)) { ns = WSSecureConversation13Constants.Namespace; identifier = WSSecureConversation13Constants.ElementNames.Identifier; instance = WSSecureConversation13Constants.ElementNames.Instance; } else { // // Something is wrong // throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException( SR.GetString(SR.ID4230, WSSecureConversationFeb2005Constants.ElementNames.Name, dicReader.Name))); } string id = dicReader.GetAttribute(WSUtilityConstants.Attributes.IdAttribute, WSUtilityConstants.NamespaceURI); dicReader.ReadFullStartElement(); if (!dicReader.IsStartElement(identifier, ns)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException( SR.GetString(SR.ID4230, WSSecureConversation13Constants.ElementNames.Identifier, dicReader.Name))); } contextId = dicReader.ReadElementContentAsUniqueId(); if (contextId == null || string.IsNullOrEmpty(contextId.ToString())) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.ID4242))); } // // The token can be a renewed token, in which case we need to know the // instance id, which will be the secondary key to the context id for // cache lookups // if (dicReader.IsStartElement(instance, ns)) { keyGeneration = dicReader.ReadElementContentAsUniqueId(); } if (dicReader.IsStartElement(CookieElementName, CookieNamespace)) { // Get the token from the Cache, which is returned as an SCT SecurityToken cachedToken = null; SecurityContextKeyIdentifierClause sctClause = null; if (keyGeneration == null) { sctClause = new SecurityContextKeyIdentifierClause(contextId); } else { sctClause = new SecurityContextKeyIdentifierClause(contextId, keyGeneration); } tokenResolver.TryResolveToken(sctClause, out cachedToken); if (cachedToken != null) { securityContextToken = cachedToken; dicReader.Skip(); } else { // // CookieMode // encodedCookie = dicReader.ReadElementContentAsBase64(); if (encodedCookie == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.ID4237))); } // // appply transforms // byte[] decodedCookie = ApplyTransforms(encodedCookie, false); using (MemoryStream ms = new MemoryStream(decodedCookie)) { BinaryFormatter formatter = new BinaryFormatter(); securityContextToken = formatter.Deserialize(ms) as SecurityToken; } SessionSecurityToken sessionToken = securityContextToken as SessionSecurityToken; if (sessionToken != null && sessionToken.ContextId != contextId) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.ID4229, sessionToken.ContextId, contextId))); } if (sessionToken != null && sessionToken.Id != id) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.ID4227, sessionToken.Id, id))); } } } else { // // SessionMode // // Get the token from the Cache. SecurityToken cachedToken = null; SecurityContextKeyIdentifierClause sctClause = null; if (keyGeneration == null) { sctClause = new SecurityContextKeyIdentifierClause(contextId); } else { sctClause = new SecurityContextKeyIdentifierClause(contextId, keyGeneration); } tokenResolver.TryResolveToken(sctClause, out cachedToken); if (cachedToken != null) { securityContextToken = cachedToken; } } dicReader.ReadEndElement(); if (securityContextToken == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.ID4243))); } return(securityContextToken); }