//----------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.IdentityModel.Tokens { /// /// A default implementation of the Token replay cache that is backed by /// a bounded cache. /// internal class DefaultTokenReplayCache : TokenReplayCache { static readonly int DefaultTokenReplayCacheCapacity = 500000; static readonly TimeSpan DefaultTokenReplayCachePurgeInterval = TimeSpan.FromMinutes(1); BoundedCache _internalCache; /// /// Constructs the default token replay cache. /// public DefaultTokenReplayCache() : this(DefaultTokenReplayCache.DefaultTokenReplayCacheCapacity, DefaultTokenReplayCache.DefaultTokenReplayCachePurgeInterval) { } /// /// Constructs the default token replay cache with the specified /// capacity and purge interval. /// /// The capacity of the token cache /// The time interval after which the cache must be purged public DefaultTokenReplayCache(int capacity, TimeSpan purgeInterval) : base() { _internalCache = new BoundedCache(capacity, purgeInterval, StringComparer.Ordinal); } /// /// Gets or Sets the current Capacity of the cache in number of SecurityTokens. /// /// If 'value' is less than or equal to zero. public int Capacity { get { return _internalCache.Capacity; } set { if (value <= 0) { throw DiagnosticUtility.ThrowHelperArgumentOutOfRange("value", value, SR.GetString(SR.ID0002)); } _internalCache.Capacity = value; } } /// /// Removes all SecurityTokens from the Cache. /// public void Clear() { _internalCache.Clear(); } /// /// Increases the maximum number of SecurityTokens that this cache will hold. /// /// The capacity to increase. /// The input parameter 'size' is less than or equal to zero. /// Updated capacity /// If size + current capacity >= int.MaxValue then capacity will be set to int.MaxValue and the cache capacity will be unbounded. public int IncreaseCapacity(int size) { if (size <= 0) { throw DiagnosticUtility.ThrowHelperArgumentOutOfRange("size", size, SR.GetString(SR.ID0002)); } return _internalCache.IncreaseCapacity(size); } /// /// Gets or Sets the time interval that will be used when checking for expired SecurityTokens. /// /// If 'value' is less than or equal to TimeSpan.Zero. public TimeSpan PurgeInterval { get { return _internalCache.PurgeInterval; } set { if (value <= TimeSpan.Zero) { throw DiagnosticUtility.ThrowHelperArgumentOutOfRange("value", value, SR.GetString(SR.ID0016)); } _internalCache.PurgeInterval = value; } } /// /// Attempt to add a new entry or update an existing entry. /// /// Key to use when adding item. /// SecurityToken to add to cache, can be null. /// The expiration instant of the token being added. /// Thrown if an attempt is made to add a SecurityToken if cache is at capacity. /// Thrown if the expiration time is infinite. public override void AddOrUpdate(string key, SecurityToken securityToken, DateTime expirationTime) { if (DateTime.Equals(expirationTime, DateTime.MaxValue)) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID1072)); } _internalCache.TryRemove(key); _internalCache.TryAdd(key, securityToken, expirationTime); } /// /// Attempt to find if a matching entry exists in the cache. /// /// The key to search for. /// true if a matching entry is ifound in the cache, false otherwise public override bool Contains(string key) { return _internalCache.TryFind(key); } /// /// Attempt to get a SecurityToken /// /// The key to search for. /// The found, if any, null otherwise. public override SecurityToken Get(string key) { SecurityToken token; _internalCache.TryGet(key, out token); return token; } /// /// Attempt to remove an entry from the cache /// /// The key to the entry to remove public override void Remove(string key) { _internalCache.TryRemove(key); } } }