1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
using System.Runtime.Serialization;
using System.Xml;
using System.IO;
namespace System.IdentityModel.Tokens
{
/// <summary>
/// Represents a serializable version of a token that can be attached to a <see cref="System.Security.Claims.ClaimsIdentity"/> to retain the
/// original token that was used to create <see cref="System.Security.Claims.ClaimsIdentity"/>
/// </summary>
[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;
}
}
/// <summary>
/// A SecurityToken and a SecurityTokenHandler that can serialize the token.
/// </summary>
/// <param name="token"><see cref="SecurityToken"/> that can be serialized. Cannot be null.</param>
/// <param name="tokenHandler"><see cref="SecurityTokenHandler"/> that is responsible for serializing the token. Cannon be null.</param>
/// <exception cref="ArgumentNullException"> thrown if 'token' or 'tokenHandler' is null.</exception>
/// <remarks>The <see cref="SecurityTokenHandler"/> is used not used to deserialize the token as it cannot be assumed to exist</remarks>
public BootstrapContext(SecurityToken token, SecurityTokenHandler tokenHandler)
{
if (token == null)
{
throw new ArgumentNullException("token");
}
if (tokenHandler == null)
{
throw new ArgumentNullException("tokenHandler");
}
_token = token;
_tokenHandler = tokenHandler;
}
/// <summary>
/// String that represents a SecurityToken.
/// </summary>
/// <param name="token">string that represents a token. Can not be null.</param>
/// <exception cref="ArgumentNullException"> thrown if 'token' is null.</exception>
public BootstrapContext(string token)
{
if (token == null)
{
throw new ArgumentNullException("token");
}
_tokenString = token;
}
/// <summary>
/// String that represents a SecurityToken.
/// </summary>
/// <param name="token">string that represents a token. Can not be null.</param>
/// <exception cref="ArgumentNullException"> thrown if 'token' is null.</exception>
public BootstrapContext(byte[] token)
{
if (token == null)
{
throw new ArgumentNullException("token");
}
_tokenBytes = token;
}
#region ISerializable Members
/// <summary>
/// Called to serialize this context.
/// </summary>
/// <param name="info"><see cref="SerializationInfo"/> container for storing data. Cannot be null.</param>
/// <param name="context"><see cref="StreamingContext"/> contains the context for streaming and optionally additional user data.</param>
/// <exception cref="ArgumentNullException"> thrown if 'info' is null.</exception>
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
/// <summary>
/// Gets the string that was passed in constructor. If a different constructor was used, will be null.
/// </summary>
public byte[] TokenBytes
{
get { return _tokenBytes; }
}
/// <summary>
/// Gets the string that was passed in constructor. If a different constructor was used, will be null.
/// </summary>
public string Token
{
get { return _tokenString; }
}
/// <summary>
/// Gets the SecurityToken that was passed in constructor. If a different constructor was used, will be null.
/// </summary>
public SecurityToken SecurityToken
{
get { return _token; }
}
/// <summary>
/// Gets the SecurityTokenHandler that was passed in constructor. If a different constructor was used, will be null.
/// </summary>
public SecurityTokenHandler SecurityTokenHandler
{
get { return _tokenHandler; }
}
}
}
|