208 lines
7.9 KiB
C#
208 lines
7.9 KiB
C#
|
//------------------------------------------------------------------------------
|
|||
|
// 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; }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|