You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 08:42:32