【发布时间】:2014-12-23 21:47:47
【问题描述】:
我正在为我的 Web 表单应用程序开发缓存功能。我想跟踪用户输入用户名(相同或不同)以阻止该 IP 的次数。
我使用 1 分钟的绝对过期时间,以便缓存对象在创建后 1 分钟后过期,无论上次访问如何。
但是,当我运行应用程序(使用 Visual Studio 开发服务器)时,除非我重建项目,否则缓存不会过期。
我在网上搜索了一些解决方案,比如设置滑动过期为NoSlidingExpiration,也可以使用自定义的计数器类来存储数据。
我还找到了一个使用system.web 标签内的 web.config 缓存元素的解决方案:
<caching>
<cache disableExpiration="false"/>
</caching>
缓存仍然没有过期。任何帮助都会很棒。这是我正在使用的代码。
private int CacheCheck()
{
// Create the keys used and retrive the values from the cahce
IncrementingCacheObject cacheUsername = Cache[KeyUsername] as IncrementingCacheObject;
IncrementingCacheObject cacheDiffAttempts = Cache[KeyDiffAttempts] as IncrementingCacheObject;
IncrementingCacheObject cacheSameAttempts = Cache[KeySameAttempts] as IncrementingCacheObject;
// Check if the username exists in cache
if (cacheUsername != null)
{
if (cacheUsername.Username.Equals(this.txtUserName.Text, StringComparison.InvariantCultureIgnoreCase))
{
if (cacheSameAttempts != null)
{
cacheSameAttempts.Count++;
this.Cache[KeySameAttempts] = cacheSameAttempts;
}
else
{
cacheSameAttempts = new IncrementingCacheObject { Count = 0, ExpireDate = DateTime.UtcNow.AddMinutes(1), Username = this.txtUserName.Text };
Cache.Insert(KeySameAttempts, cacheSameAttempts, null, cacheSameAttempts.ExpireDate, System.Web.Caching.Cache.NoSlidingExpiration);
}
}
else
{
if (cacheDiffAttempts != null)
{
cacheDiffAttempts.Count++;
this.Cache[KeyDiffAttempts] = cacheDiffAttempts;
}
else
{
cacheDiffAttempts = new IncrementingCacheObject { Count = 0, ExpireDate = DateTime.UtcNow.AddMinutes(1), Username = this.txtUserName.Text };
Cache.Insert(KeyDiffAttempts, cacheDiffAttempts, null, cacheDiffAttempts.ExpireDate, System.Web.Caching.Cache.NoSlidingExpiration);
}
}
// Set the last used username value in the Cache to the value in the text box
cacheUsername.Username = this.txtUserName.Text;
this.Cache[KeyUsername] = cacheUsername;
}
else
{
cacheUsername = new IncrementingCacheObject { Count = 0, ExpireDate = DateTime.UtcNow.AddMinutes(1), Username = this.txtUserName.Text };
cacheDiffAttempts = new IncrementingCacheObject { Count = 0, ExpireDate = DateTime.UtcNow.AddMinutes(1), Username = this.txtUserName.Text };
cacheSameAttempts = new IncrementingCacheObject { Count = 0, ExpireDate = DateTime.UtcNow.AddMinutes(1), Username = this.txtUserName.Text };
Cache.Insert(KeyUsername, cacheUsername, null, cacheUsername.ExpireDate, System.Web.Caching.Cache.NoSlidingExpiration);
Cache.Insert(KeySameAttempts, cacheSameAttempts, null, cacheSameAttempts.ExpireDate, System.Web.Caching.Cache.NoSlidingExpiration);
Cache.Insert(KeyDiffAttempts, cacheDiffAttempts, null, cacheDiffAttempts.ExpireDate, System.Web.Caching.Cache.NoSlidingExpiration);
}
cacheUsername = Cache[KeyUsername] as IncrementingCacheObject;
cacheDiffAttempts = Cache[KeyDiffAttempts] as IncrementingCacheObject;
cacheSameAttempts = Cache[KeySameAttempts] as IncrementingCacheObject;
// Check whether any log in attempts have surpassed the threshold and return a value to indicate what kind of log in was detected
if (cacheDiffAttempts != null && cacheDiffAttempts.Count >= MaxLogAttemptsBeforeBan)
{
return 0;
}
if (cacheSameAttempts != null && cacheSameAttempts.Count >= MaxLogAttemptsBeforeBan)
{
return 1;
}
return -1;
}
/// <summary>
/// This will reset the cache to blank/starting values.
/// </summary>
private void ResetCache()
{
Cache.Remove(KeyUsername);
Cache.Remove(KeySameAttempts);
Cache.Remove(KeyDiffAttempts);
}
// Class used to store objects in the cache
private class IncrementingCacheObject
{
public string Username;
public int Count;
public DateTime ExpireDate;
}
当用户登录成功后,在页面被重定向之前,会调用ResetCache()方法。
【问题讨论】:
-
您是否查看过使用会员服务提供商的最大登录尝试次数? msdn.microsoft.com/en-us/library/…
-
您是否设置了缓存策略的绝对过期属性?
-
限制数据库交互可能是一个可以说是合理的理由...但会提供更长期的安全性...如果您的缓存在用户多次登录尝试中途过期怎么办...如果您将尝试限制为 5 次,并且他们每天进行 4 次,持续 6 个月,直到他们进入?
-
@RXC 我建议使用 CacheItemPriority 并将其设置得尽可能高,同时牢记您的系统限制,以尽量减少正在擦除的缓存。
-
@RXC 另外,您为什么不像在您使用的解决方案中那样使用 HttpContext.Current.Cache ?这很可能会混淆您当前的缓存未过期问题。
标签: c# asp.net caching webforms