Azureweb-farm准备好SecurityTokenCache

Azureweb-farm准备好SecurityTokenCache,第1张

概述我们的网站使用ADFS进行验证。为了减少每个请求的cookie有效负载,我们正在转动IsSessionMode(参见 Your fedauth cookies on a diet)。 我们需要做的最后一件事是让我们在负载平衡的环境中工作,就是实现一个农场准备好的SecurityTokenCache。实现看起来很简单,我主要感兴趣的是发现在处理SecurityTokenCacheKey和TryGet 我们的网站使用ADFS进行验证。为了减少每个请求的cookie有效负载,我们正在转动IsSessionMode(参见 Your fedauth cookies on a diet)。

我们需要做的最后一件事是让我们在负载平衡的环境中工作,就是实现一个农场准备好的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。

解决方法 为了想出一个工作实现,我们最终不得不使用反射器来分析Microsoft.IDentityModel中不同的SessionSecurityToken相关的类。下面是我们想出来的这个实现部署在我们的开发环境和qa环境中,似乎工作正常,它对应用程序池的循环利用是很重要的。

在全球:

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所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1113842.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存