我们需要做的最后一件事是让我们在负载平衡的环境中工作,就是实现一个农场准备好的SecurityTokenCache。实现看起来很简单,我主要感兴趣的是发现在处理SecurityTokenCacheKey和TryGetAllEntrIEs和TryRemoveAllEntrIEs方法时,我们应该考虑什么问题(SecurityTokenCacheKey具有Equals和GetHashCode方法的自定义实现)。
有人有这个例子吗?我们正在计划使用AppFabric作为后备存储,但使用任何持久存储的示例将是有用的 – 数据库表,Azure表存储等。
以下是我搜索过的一些地方:
>在Hervey Wilson’s PDC09
session他使用a
DatabaseSecurityTokenCache。我找不到样本
他的会话代码
> Vittorio Bertocci的出色的第192页
他写道,“编程windows身份基金会”他提到上传
Azure的一个示例实现ReadyTokenCache到
书的网站。我还没有找到这个样本。
谢谢!
JD
3/16/2012更新
Vittorio’s blog链接到一个示例使用新的.net 4.5的东西:
ClaimsAwareWebFarm
这个样本是我们从许多人得到的反馈的答案:你想要一个示例显示一个农场准备好的会话缓存(而不是一个tokenreplycache),以便您可以通过引用使用会话而不是交换大的cookie;您要求在农场中更容易地保护cookie。
在全球:
protected voID Application_Start(object sender,EventArgs e){ FederatedAuthentication.ServiceConfigurationCreated += this.OnServiceConfigurationCreated;}private voID OnServiceConfigurationCreated(object sender,ServiceConfigurationCreatedEventArgs e){ var sessiontransforms = new List<cookietransform>(new cookietransform[] { new Deflatecookietransform(),new RSAEncryptioncookietransform( e.ServiceConfiguration.ServiceCertificate),new RsaSignaturecookietransform( e.ServiceConfiguration.ServiceCertificate) }); // following line is pseudo code. use your own durable cache implementation. var durableCache = new AppFabricCacheWrapper(); var tokenCache = new DurableSecurityTokenCache(durableCache,5000); var sessionHandler = new SessionSecurityTokenHandler(sessiontransforms.AsReadonly(),tokenCache,TimeSpan.FromDays(1)); e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler);}private voID WSFederationAuthenticationModule_SecurityTokenValIDated(object sender,SecurityTokenValIDatedEventArgs e){ FederatedAuthentication.SessionAuthenticationModule.IsSessionMode = true;}
DurableSecurityTokenCache.cs:
/// <summary>/// Two level durable security token cache (level 1: in memory MRU,level 2: out of process cache)./// </summary>public class DurableSecurityTokenCache : SecurityTokenCache{ private ICache<string,byte[]> durableCache; private Readonly MruCache<SecurityTokenCacheKey,SecurityToken> mruCache; /// <summary> /// The constructor. /// </summary> /// <param name="durableCache">The durable second level cache (should be out of process IE sql server,azure table,app fabric,etc).</param> /// <param name="mruCapacity">Capacity of the internal first level cache (in-memory MRU cache).</param> public DurableSecurityTokenCache(ICache<string,byte[]> durableCache,int mruCapacity) { this.durableCache = durableCache; this.mruCache = new MruCache<SecurityTokenCacheKey,SecurityToken>(mruCapacity,mruCapacity / 4); } public overrIDe bool TryAddEntry(object key,SecurityToken value) { var cacheKey = (SecurityTokenCacheKey)key; // add the entry to the mru cache. this.mruCache.Add(cacheKey,value); // add the entry to the durable cache. var keyString = GetKeyString(cacheKey); var buffer = this.GetSerializer().Serialize((SessionSecurityToken)value); this.durableCache.Add(keyString,buffer); return true; } public overrIDe bool TryGetEntry(object key,out SecurityToken value) { var cacheKey = (SecurityTokenCacheKey)key; // attempt to retrIEve the entry from the mru cache. value = this.mruCache.Get(cacheKey); if (value != null) return true; // entry wasn't in the mru cache,retrIEve it from the app fabric cache. var keyString = GetKeyString(cacheKey); var buffer = this.durableCache.Get(keyString); var result = buffer != null; if (result) { // we had a cache miss in the mru cache but found the item in the durable cache... // deserialize the value retrIEved from the durable cache. value = this.GetSerializer().Deserialize(buffer); // push this item into the mru cache. this.mruCache.Add(cacheKey,value); } return result; } public overrIDe bool TryRemoveEntry(object key) { var cacheKey = (SecurityTokenCacheKey)key; // remove the entry from the mru cache. this.mruCache.Remove(cacheKey); // remove the entry from the durable cache. var keyString = GetKeyString(cacheKey); this.durableCache.Remove(keyString); return true; } public overrIDe bool TryReplaceEntry(object key,SecurityToken newValue) { var cacheKey = (SecurityTokenCacheKey)key; // remove the entry in the mru cache. this.mruCache.Remove(cacheKey); // remove the entry in the durable cache. var keyString = GetKeyString(cacheKey); // add the new value. return this.TryAddEntry(key,newValue); } public overrIDe bool TryGetAllEntrIEs(object key,out IList<SecurityToken> tokens) { // not implemented... haven't been able to find how/when this method is used. tokens = new List<SecurityToken>(); return true; //throw new NotImplementedException(); } public overrIDe bool TryRemoveAllEntrIEs(object key) { // not implemented... haven't been able to find how/when this method is used. return true; //throw new NotImplementedException(); } public overrIDe voID ClearEntrIEs() { // not implemented... haven't been able to find how/when this method is used. //throw new NotImplementedException(); } /// <summary> /// Gets the string representation of the specifIEd SecurityTokenCacheKey. /// </summary> private string GetKeyString(SecurityTokenCacheKey key) { return string.Format("{0}; {1}; {2}",key.ContextID,key.KeyGeneration,key.EndpointID); } /// <summary> /// Gets a new instance of the token serializer. /// </summary> private SessionSecurityTokencookieSerializer GetSerializer() { return new SessionSecurityTokencookieSerializer(); // may need to do something about handling bootstrap tokens. }}
MruCache.cs:
/// <summary>/// Most recently used (MRU) cache./// </summary>/// <typeparam name="TKey">The key type.</typeparam>/// <typeparam name="TValue">The value type.</typeparam>public class MruCache<TKey,TValue> : ICache<TKey,TValue>{ private Dictionary<TKey,TValue> mruCache; private linkedList<TKey> mruList; private object syncRoot; private int capacity; private int sizeAfterPurge; /// <summary> /// The constructor. /// </summary> /// <param name="capacity">The capacity.</param> /// <param name="sizeAfterPurge">Size to make the cache after purging because it's reached capacity.</param> public MruCache(int capacity,int sizeAfterPurge) { this.mruList = new linkedList<TKey>(); this.mruCache = new Dictionary<TKey,TValue>(capacity); this.capacity = capacity; this.sizeAfterPurge = sizeAfterPurge; this.syncRoot = new object(); } /// <summary> /// Adds an item if it doesn't already exist. /// </summary> public voID Add(TKey key,TValue value) { lock (this.syncRoot) { if (mruCache.ContainsKey(key)) return; if (mruCache.Count + 1 >= this.capacity) { while (mruCache.Count > this.sizeAfterPurge) { var lru = mruList.Last.Value; mruCache.Remove(lru); mruList.RemoveLast(); } } mruCache.Add(key,value); mruList.AddFirst(key); } } /// <summary> /// Removes an item if it exists. /// </summary> public voID Remove(TKey key) { lock (this.syncRoot) { if (!mruCache.ContainsKey(key)) return; mruCache.Remove(key); mruList.Remove(key); } } /// <summary> /// Gets an item. If a matching item doesn't exist null is returned. /// </summary> public TValue Get(TKey key) { lock (this.syncRoot) { if (!mruCache.ContainsKey(key)) return default(TValue); mruList.Remove(key); mruList.AddFirst(key); return mruCache[key]; } } /// <summary> /// Gets whether a key is contained in the cache. /// </summary> public bool ContainsKey(TKey key) { lock (this.syncRoot) return mruCache.ContainsKey(key); }}
ICache.cs:
/// <summary>/// A cache./// </summary>/// <typeparam name="TKey">The key type.</typeparam>/// <typeparam name="TValue">The value type.</typeparam>public interface ICache<TKey,TValue>{ voID Add(TKey key,TValue value); voID Remove(TKey key); TValue Get(TKey key);}总结
以上是内存溢出为你收集整理的Azure/web-farm准备好SecurityTokenCache全部内容,希望文章能够帮你解决Azure/web-farm准备好SecurityTokenCache所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)