几个月前,我们遇到了一次严重的 SharePoint 中断,原因是用户将键盘卡在了某个位置,导致 Enter 键一直被按下。该用户当时正在访问自定义的人员搜索页面,该用户异步提交了数百条 POST,导致服务器超负荷。
因为我在一个大型组织工作,所以我正在寻找一种更全面的方式来防止这种情况发生。
有没有办法可以防止普通用户在 IIS 中短时间内多次提交 Web 表单?
我知道我们可以编写 javascript 来在单击按钮后禁用该按钮,但我们希望防止此问题发生在可能存在类似可能性的其他页面上。
更新:查看源代码后发现,每当按下键码 13(Enter)时,javascript 就会执行 document.location = url。同样,我们可以在此位置编写 JS 来阻止这种情况,但我们也希望能够更普遍地防范此类问题……最好是在 IIS 级别。
答案1
对此的一个选择是使用类似以下方法进行速率限制http://www.iis.net/downloads/microsoft/dynamic-ip-restrictions可以设置为在一定时间内阻止违规 IP。
当然,在将这样的事情投入生产之前,你会希望对典型的请求/秒/IP进行基准测试,但这应该可以防止单个用户再次执行这样的事情。
答案2
如果问题只是避免因并发请求数量而产生的影响,则可以使用 IIS 7 的附加组件“动态 IP 限制”。 (此功能现在已内置于 IIS8 中)。 可以将其配置为仅日志模式,以确定在启用此功能之前是否会产生影响。
http://www.iis.net/downloads/microsoft/dynamic-ip-restrictions
- 无缝集成到 IIS 7.0 管理器。
- 根据以下任一标准动态阻止来自 IP 地址的请求:
- 并发请求的数量。
- 一段时间内的请求数量。
- 支持允许绕过动态 IP 限制过滤的 IP 列表。
- 可以在网站或 Web 服务器级别配置请求的阻止。
- 可配置的拒绝操作允许 IT 管理员指定返回给客户端的响应。该模块支持返回状态代码 403、404 或关闭连接。
- 支持 IPv6 地址。
- 支持可能修改客户端 IP 地址的代理或防火墙后面的 Web 服务器。
多个表单提交应该在应用程序级别解决。使用母版页很容易实现。母版页中的以下 jquery 可对所有子内容页执行此操作:
$("form").submit(function () {
$(":submit", this).attr("disabled", "disabled");
});
另一个值得采用的好做法是:Post/Redirect/Get
答案3
您可以编写一个全局级 IIS 模块并检查在特定的短时间内是否来自同一用户的相同请求。然后您可以决定是否允许请求继续。
class CGlobalTestFilterModule:public CGlobalModule
{
public:
GLOBAL_NOTIFICATION_STATUS
OnGlobalPreBeginRequest(IN IPreBeginRequestProvider * pProvider)
{
...
}
...
}
这里有一个实现 IIS 模块的良好指南: http://www.iis.net/learn/develop/runtime-extensibility/develop-a-native-cc-module-for-iis 如果你更熟悉.NET,你可以选择托管模块