我有一个 Blazor 服务器应用程序,它正在使用 ASP.NET Core 身份库(即 MVC)。
我想实现代码,以便如果远程 IP 地址在 15 分钟内登录失败 50 次,我会阻止该 IP 地址登录 4 小时。
除了 Login.cshtml.cs 之外,我还需要观看其他内容吗?我假设在那里我可以观察
OnPostAsync()
是否有失败,并在失败时获取 IP 地址。并且在进入时,如果超出限制,则立即返回错误。
在
Dictionary<IP_Address,Count>
中追踪这一切有什么问题吗?
我将使用 FrontDoor 在 Azure 上运行。有没有办法让 FrontDoor 在一段时间内忽略某个 IP 地址?我认为如果是这样,那就比尝试一直到我的代码更好。
我是否遗漏了什么?
你可以尝试:
//inject IMemoryCache
private readonly IMemoryCache _cache;
public void OnPost()
{
//when you failed to login
var ipAddress = HttpContext.Connection.RemoteIpAddress;
var hasrecords=_cache.TryGetValue(ipAddress, out var records);
if (!hasrecords)
{
var datetimeArr = new List<DateTime> { DateTime.Now };
_cache.Set(ipAddress, datetimeArr, DateTimeOffset.Now.AddMinutes(40));
}
else
{
var datetimeArr= records as List<DateTime>;
datetimeArr?.Add(DateTime.Now );
_cache.Set(ipAddress, datetimeArr, DateTimeOffset.Now.AddMinutes(40));
}
}
public override async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context,
PageHandlerExecutionDelegate next)
{
var ipAddress = HttpContext.Connection.RemoteIpAddress;
var hasrecords = _cache.TryGetValue(ipAddress, out var records);
if (hasrecords)
{
var count = (records as List<DateTime>).Where(x => x.CompareTo(DateTime.Now.AddMinutes(-15)) > 0).ToArray().Count();
if (count >= 40)
{
//block here
context.Result = new ObjectResult("Forbid");
}
else
{
await next.Invoke();
}
}
else
{
await next.Invoke();
}
}