Art*_*iom 4 c# asp.net security iis wcf
我的IIS使用WebService资源托管WebApp.
同样的坏人,试图阻止服务器访问公共资源与他们的机器人.
我建立一个过滤器:
public class BadGuysFilter
{
private class BadGuy
{
public BadGuy()
{
Visits = 0;
FirstSuspiciousVisit = DateTime.Now;
}
public int Visits;
public DateTime FirstSuspiciousVisit;
}
private static volatile Dictionary<string, BadGuy> _blackList = new Dictionary<string, BadGuy>();
private static int _visitsLimit = 10;
private static int _minutsLimit = 10;
private static int _removeFromBlackListMinutesLimit = 30;
public static void Init(int visitsLimit = 10, int minutsLimit = 10, int removeFromBlackListMinutesLimit = 30)
{
_visitsLimit = visitsLimit;
_minutsLimit = minutsLimit;
_removeFromBlackListMinutesLimit = removeFromBlackListMinutesLimit;
}
public static bool IsBadGuy()
{
return IsBadGuy(HttpContext.Current.Request.UserHostAddress);
}
public static bool IsBadGuy(string ip)
{
if (HttpContext.Current.Request.IsAuthenticated /*|| HttpContext.Current.Request.HttpMethod.ToUpper() == "POST"*/)
return false;
if (_blackList.Keys.Any(k => k == ip))
{
_blackList[ip].Visits++;
if (_blackList[ip].FirstSuspiciousVisit < DateTime.Now.AddMinutes(-_removeFromBlackListMinutesLimit))
_blackList.Remove(ip);
else if (_blackList[ip].FirstSuspiciousVisit < DateTime.Now.AddMinutes(-_minutsLimit))
{
_blackList[ip].Visits = 0;
_blackList[ip].FirstSuspiciousVisit = DateTime.Now;
}
else if (_blackList[ip].Visits > _visitsLimit)
{
_blackList[ip].FirstSuspiciousVisit = DateTime.Now;
return true;
}
}
else
_blackList.Add(ip, new BadGuy());
return false;
}
public static void Punish()
{
var res = HttpContext.Current.Response;
res.Clear();
res.StatusCode = 429;
res.StatusDescription = "TOO MANY REQUESTS: Your application is sending too many simultaneous requests.";
res.End();
}
}
Run Code Online (Sandbox Code Playgroud)在Global.asax中使用过滤器
void Application_BeginRequest(object sender, EventArgs e) {
if(BadGuysFilter.IsBadGuy())
BadGuysFilter.Punish();
// do stuff //
}
void Application_EndRequest(object sender, EventArgs e) {
var app = (HttpApplication)sender;
if (app.Context.Response.StatusCode == 429) // "TOO MANY REQUESTS"
return;
// do stuff //
}
Run Code Online (Sandbox Code Playgroud)这是一个足够安全的解决方案?或许还有另一种方式?
Edite: "不要阻塞资源本身.阻止更远的上游,例如在防火墙上. - Marc B"是的,你是对的.这是最终解决方案,但在应用之前,我需要中间解决方案来保护我的服务器.我忘了提这件事. - Artiom