//----------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------- namespace System.IdentityModel.Tokens { using System.Text; using SystemUniqueId = System.Xml.UniqueId; /// /// When caching an there are two indexes required. One is the ContextId /// that is unique across all and the next is KeyGeneration which is /// unique within a session. When an is issued it has only a ContextId. When /// the is renewed the KeyGeneration is added as an second index to the /// . Now the renewed is uniquely identifiable via the ContextId and /// KeyGeneration. /// The class is used as the index /// to the cache. This index will always have a valid ContextId specified /// but the KeyGeneration may be null. There is also an optional EndpointId /// which gives the endpoint to which the token is scoped. /// public class SessionSecurityTokenCacheKey { private SystemUniqueId contextId; private SystemUniqueId keyGeneration; private string endpointId; private bool ignoreKeyGeneration; /// /// Creates an instance of which /// is used as an index while caching . /// /// The endpoint Id to which the is scoped. /// UniqueId of the . /// UniqueId which is available when the is renewed. Will be /// null when caching a new . public SessionSecurityTokenCacheKey(string endpointId, System.Xml.UniqueId contextId, System.Xml.UniqueId keyGeneration) { if (endpointId == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointId"); } if (contextId == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contextId"); } this.endpointId = endpointId; this.contextId = contextId; this.keyGeneration = keyGeneration; } /// /// Gets or sets a value indicating whether KeyGeneration can be ignored /// while doing index comparison. /// public bool IgnoreKeyGeneration { get { return this.ignoreKeyGeneration; } set { this.ignoreKeyGeneration = value; } } /// /// Gets the ContextId of the /// public System.Xml.UniqueId ContextId { get { return this.contextId; } } /// /// Gets the EndpointId to which this cache entry is scoped. /// public string EndpointId { get { return this.endpointId; } } /// /// Gets the KeyGeneration of the /// public System.Xml.UniqueId KeyGeneration { get { return this.keyGeneration; } } /// /// Implements the equality operator for . /// /// First object to compare. /// Second object to compare. /// 'true' if both objects are equal. public static bool operator ==(SessionSecurityTokenCacheKey first, SessionSecurityTokenCacheKey second) { if (object.ReferenceEquals(first, null)) { return object.ReferenceEquals(second, null); } return first.Equals(second); } /// /// Implements the inequality operator for . /// /// First object to compare. /// Second object to compare. /// 'true' if both the objects are different. public static bool operator !=(SessionSecurityTokenCacheKey first, SessionSecurityTokenCacheKey second) { return !(first == second); } /// /// Checks if the given object is the same as the current object. /// /// The object to be compared. /// 'true' if both are the same object else false. public override bool Equals(object obj) { if (obj is SessionSecurityTokenCacheKey) { SessionSecurityTokenCacheKey key2 = obj as SessionSecurityTokenCacheKey; if (key2.ContextId != this.contextId) { return false; } if (!StringComparer.Ordinal.Equals(key2.EndpointId, this.endpointId)) { return false; } // If KeyGeneration can be ignored on either one of them then we // don't do KeyGeneration comparison. if (!this.ignoreKeyGeneration && !key2.IgnoreKeyGeneration) { return key2.KeyGeneration == this.keyGeneration; } return true; } return false; } /// /// Returns a Hash code for this object. /// /// Hash code for the object as a Integer. public override int GetHashCode() { if (this.keyGeneration == null) { return this.contextId.GetHashCode(); } else { return this.contextId.GetHashCode() ^ this.keyGeneration.GetHashCode(); } } /// /// Implements ToString() to provide a unique identifier. /// /// This key, in string form. public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append(this.endpointId); sb.Append(';'); sb.Append(this.contextId.ToString()); sb.Append(';'); if (!this.ignoreKeyGeneration && this.keyGeneration != null) { sb.Append(this.keyGeneration.ToString()); } return sb.ToString(); } } }