如何在IIS上针对所有IP限制网站登录尝试次数?
IIS网站登录尝试次数限制方案(支持非IP维度的速率控制)
一、基于现有Basic认证的改造方案
原生IIS Basic认证无内置的非IP维度速率限制,可通过应用层逻辑或IIS扩展实现:
1. 应用层自定义速率控制(ASP.NET Core)
无需更换认证方式,通过中间件捕获Basic认证用户名,结合缓存实现按用户的失败次数限制:
- 解析请求头中的
Authorization字段,提取Basic认证的用户名 - 用内存缓存/分布式缓存记录每个用户的失败尝试次数与时间窗口
- 达到阈值后返回
429 Too Many Requests,同时执行日志记录、告警等失败操作
示例代码:
public class LoginRateLimitMiddleware { private readonly RequestDelegate _next; private readonly IMemoryCache _cache; // 可根据业务调整阈值与锁定时长 private const int MaxFailedAttempts = 5; private const int LockoutMinutes = 15; public LoginRateLimitMiddleware(RequestDelegate next, IMemoryCache cache) { _next = next; _cache = cache; } public async Task InvokeAsync(HttpContext context) { var authHeader = context.Request.Headers.Authorization.FirstOrDefault(); if (!string.IsNullOrEmpty(authHeader) && authHeader.StartsWith("Basic ")) { var encodedCreds = authHeader.Substring("Basic ".Length).Trim(); var creds = Encoding.UTF8.GetString(Convert.FromBase64String(encodedCreds)); var username = creds.Split(':')[0]; var cacheKey = $"LoginFailed:{username}"; if (_cache.TryGetValue(cacheKey, out int failedAttempts) && failedAttempts >= MaxFailedAttempts) { context.Response.StatusCode = StatusCodes.Status429TooManyRequests; await context.Response.WriteAsync("Too many failed login attempts. Try again later."); // 执行失败后操作:记录审计日志、发送告警邮件 LogLockoutEvent(username); return; } await _next(context); // 认证失败时更新缓存计数 if (context.Response.StatusCode == StatusCodes.Status401Unauthorized) { var currentAttempts = _cache.Get<int>(cacheKey); _cache.Set(cacheKey, currentAttempts + 1, TimeSpan.FromMinutes(LockoutMinutes)); } } else { await _next(context); } } private void LogLockoutEvent(string username) { // 自定义日志/告警逻辑实现 } } // 在Program.cs中注册中间件(需置于认证中间件之前) app.UseMiddleware<LoginRateLimitMiddleware>(); app.UseAuthentication(); app.UseAuthorization();
2. IIS URL重写模块+自定义脚本
针对传统ASP.NET或不愿修改应用代码的场景,可通过IIS URL重写模块拦截请求,配合脚本实现限制:
- 配置重写规则,拦截携带Basic认证头的登录请求
- 提取用户名,通过脚本查询本地存储(XML/数据库)的失败次数
- 超过阈值时直接返回429状态码,并触发失败操作
二、更换IIS认证方式实现限制
1. 改用Forms认证(ASP.NET)
Forms认证内置用户失败次数锁定机制,可通过配置快速实现:
- 在
web.config中配置membership节点,设置失败次数阈值与锁定窗口 - 认证失败后自动锁定用户,支持自定义锁定后的日志、告警逻辑
示例配置:
<membership defaultProvider="AspNetSqlMembershipProvider"> <providers> <clear/> <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" passwordAttemptWindow="15" applicationName="/"/> </providers> </membership>
2. 改用Windows认证(域环境)
若网站部署在域内,可结合AD账户锁定策略实现:
- 在AD组策略中配置账户锁定阈值、锁定时长
- 登录失败达到次数后,AD自动锁定账户,同时支持通过组策略配置失败告警与日志
三、服务器层面工具实现限制
1. IIS Advanced URL Rewrite扩展
安装第三方URL重写扩展,支持按用户名维度的速率规则配置:
- 从请求头提取用户名,扩展内置缓存记录失败次数
- 配置规则达到阈值后拦截请求,触发自定义脚本执行失败操作
2. 安装ModSecurity WAF模块
通过IIS的ModSecurity模块配置规则,检测并限制登录失败请求:
- 规则识别Basic认证的401失败响应,按用户名统计失败次数
- 超过阈值后拦截请求,同时记录审计日志、发送告警
内容的提问来源于stack exchange,提问作者azureuser01
相关产品推荐
相关产品推荐

