//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ using System.Runtime.Serialization; using System.Xml; using System.IO; namespace System.IdentityModel.Tokens { /// /// Represents a serializable version of a token that can be attached to a to retain the /// original token that was used to create /// [Serializable] public class BootstrapContext : ISerializable { SecurityToken _token; string _tokenString; byte[] _tokenBytes; SecurityTokenHandler _tokenHandler; const string _tokenTypeKey = "K"; const string _tokenKey = "T"; const char _securityTokenType = 'T'; const char _stringTokenType = 'S'; const char _byteTokenType = 'B'; protected BootstrapContext(SerializationInfo info, StreamingContext context) { if (info == null) return; switch (info.GetChar(_tokenTypeKey)) { case _securityTokenType: { SecurityTokenHandler sth = context.Context as SecurityTokenHandler; if (sth != null) { using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(Convert.FromBase64String(info.GetString(_tokenKey)), XmlDictionaryReaderQuotas.Max)) { reader.MoveToContent(); if (sth.CanReadToken(reader)) { string tokenName = reader.LocalName; string tokenNamespace = reader.NamespaceURI; SecurityToken token = sth.ReadToken(reader); if (token == null) { _tokenString = Text.Encoding.UTF8.GetString(Convert.FromBase64String(info.GetString(_tokenKey))); } else { _token = token; } } } } else { _tokenString = Text.Encoding.UTF8.GetString(Convert.FromBase64String(info.GetString(_tokenKey))); } } break; case _stringTokenType: { _tokenString = info.GetString(_tokenKey); } break; case _byteTokenType: { _tokenBytes = (byte[])info.GetValue(_tokenKey, typeof(byte[])); } break; default: break; } } /// /// A SecurityToken and a SecurityTokenHandler that can serialize the token. /// /// that can be serialized. Cannot be null. /// that is responsible for serializing the token. Cannon be null. /// thrown if 'token' or 'tokenHandler' is null. /// The is used not used to deserialize the token as it cannot be assumed to exist public BootstrapContext(SecurityToken token, SecurityTokenHandler tokenHandler) { if (token == null) { throw new ArgumentNullException("token"); } if (tokenHandler == null) { throw new ArgumentNullException("tokenHandler"); } _token = token; _tokenHandler = tokenHandler; } /// /// String that represents a SecurityToken. /// /// string that represents a token. Can not be null. /// thrown if 'token' is null. public BootstrapContext(string token) { if (token == null) { throw new ArgumentNullException("token"); } _tokenString = token; } /// /// String that represents a SecurityToken. /// /// string that represents a token. Can not be null. /// thrown if 'token' is null. public BootstrapContext(byte[] token) { if (token == null) { throw new ArgumentNullException("token"); } _tokenBytes = token; } #region ISerializable Members /// /// Called to serialize this context. /// /// container for storing data. Cannot be null. /// contains the context for streaming and optionally additional user data. /// thrown if 'info' is null. public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { if (_tokenBytes != null) { info.AddValue(_tokenTypeKey, _byteTokenType); info.AddValue(_tokenKey, _tokenBytes); } else if (_tokenString != null) { info.AddValue(_tokenTypeKey, _stringTokenType); info.AddValue(_tokenKey, _tokenString); } else if (_token != null && _tokenHandler != null) { using (MemoryStream ms = new MemoryStream()) { info.AddValue(_tokenTypeKey, _securityTokenType); using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(ms, Text.Encoding.UTF8, false)) { _tokenHandler.WriteToken(writer, _token); writer.Flush(); info.AddValue(_tokenKey, Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length)); } } } } #endregion /// /// Gets the string that was passed in constructor. If a different constructor was used, will be null. /// public byte[] TokenBytes { get { return _tokenBytes; } } /// /// Gets the string that was passed in constructor. If a different constructor was used, will be null. /// public string Token { get { return _tokenString; } } /// /// Gets the SecurityToken that was passed in constructor. If a different constructor was used, will be null. /// public SecurityToken SecurityToken { get { return _token; } } /// /// Gets the SecurityTokenHandler that was passed in constructor. If a different constructor was used, will be null. /// public SecurityTokenHandler SecurityTokenHandler { get { return _tokenHandler; } } } }