懒得勤快 3 лет назад
Родитель
Сommit
41e4183f57

+ 95 - 91
src/Masuit.MyBlogs.Core/Controllers/FirewallController.cs

@@ -1,5 +1,4 @@
-using System.Net;
-using System.Web;
+using System.Web;
 using CacheManager.Core;
 using Masuit.MyBlogs.Core.Common;
 using Masuit.MyBlogs.Core.Configs;
@@ -15,111 +14,116 @@ using Microsoft.AspNetCore.Mvc;
 using Microsoft.Net.Http.Headers;
 using SameSiteMode = Microsoft.AspNetCore.Http.SameSiteMode;
 
-namespace Masuit.MyBlogs.Core.Controllers
+namespace Masuit.MyBlogs.Core.Controllers;
+
+public class FirewallController : Controller
 {
-    public class FirewallController : Controller
+    /// <summary>
+    /// JS挑战,5秒盾
+    /// </summary>
+    /// <param name="token"></param>
+    /// <returns></returns>
+    [HttpPost("/challenge"), AutoValidateAntiforgeryToken]
+    public ActionResult JsChallenge()
     {
-        /// <summary>
-        /// JS挑战,5秒盾
-        /// </summary>
-        /// <param name="token"></param>
-        /// <returns></returns>
-        [HttpPost("/challenge"), AutoValidateAntiforgeryToken]
-        public ActionResult JsChallenge()
+        try
         {
-            try
-            {
-                HttpContext.Session.Set("js-challenge", 1);
-                Response.Cookies.Append(SessionKey.ChallengeBypass, DateTime.Now.AddSeconds(new Random().Next(60, 86400)).ToString("yyyy-MM-dd HH:mm:ss").AESEncrypt(AppConfig.BaiduAK), new CookieOptions()
-                {
-                    SameSite = SameSiteMode.Lax,
-                    Expires = DateTime.Now.AddDays(1)
-                });
-                return Ok();
-            }
-            catch
+            HttpContext.Session.Set("js-challenge", 1);
+            Response.Cookies.Append(SessionKey.ChallengeBypass, DateTime.Now.AddSeconds(new Random().Next(60, 86400)).ToString("yyyy-MM-dd HH:mm:ss").AESEncrypt(AppConfig.BaiduAK), new CookieOptions()
             {
-                return BadRequest();
-            }
+                SameSite = SameSiteMode.Lax,
+                Expires = DateTime.Now.AddDays(1)
+            });
+            return Ok();
         }
+        catch
+        {
+            return BadRequest();
+        }
+    }
 
-        /// <summary>
-        /// 验证码挑战
-        /// </summary>
-        /// <param name="code"></param>
-        /// <returns></returns>
-        [HttpPost("/captcha"), AutoValidateAntiforgeryToken]
-        public ActionResult CaptchaChallenge(string code)
+    /// <summary>
+    /// 验证码挑战
+    /// </summary>
+    /// <param name="code"></param>
+    /// <returns></returns>
+    [HttpPost("/captcha"), AutoValidateAntiforgeryToken]
+    public ActionResult CaptchaChallenge(string code)
+    {
+        if (string.IsNullOrEmpty(code) || code.Length < 4)
         {
-            if (string.IsNullOrEmpty(code) || code.Length < 4)
-            {
-                return BadRequest("验证码无效");
-            }
+            return BadRequest("验证码无效");
+        }
 
-            if (code.Equals(HttpContext.Session.Get<string>("challenge-captcha"), StringComparison.CurrentCultureIgnoreCase))
+        if (code.Equals(HttpContext.Session.Get<string>("challenge-captcha"), StringComparison.CurrentCultureIgnoreCase))
+        {
+            HttpContext.Session.Set("js-challenge", 1);
+            HttpContext.Session.Remove("challenge-captcha");
+            Response.Cookies.Append(SessionKey.ChallengeBypass, DateTime.Now.AddSeconds(new Random().Next(60, 86400)).ToString("yyyy-MM-dd HH:mm:ss").AESEncrypt(AppConfig.BaiduAK), new CookieOptions()
             {
-                HttpContext.Session.Set("js-challenge", 1);
-                HttpContext.Session.Remove("challenge-captcha");
-                Response.Cookies.Append(SessionKey.ChallengeBypass, DateTime.Now.AddSeconds(new Random().Next(60, 86400)).ToString("yyyy-MM-dd HH:mm:ss").AESEncrypt(AppConfig.BaiduAK), new CookieOptions()
-                {
-                    SameSite = SameSiteMode.Lax,
-                    Expires = DateTime.Now.AddDays(1)
-                });
-            }
-
-            return Redirect(Request.Headers[HeaderNames.Referer]);
+                SameSite = SameSiteMode.Lax,
+                Expires = DateTime.Now.AddDays(1)
+            });
         }
 
-        /// <summary>
-        /// 验证码
-        /// </summary>
-        /// <returns></returns>
-        [HttpGet("/challenge-captcha.jpg")]
-        [ResponseCache(NoStore = true, Duration = 0)]
-        public ActionResult CaptchaChallenge()
+        return Redirect(Request.Headers[HeaderNames.Referer]);
+    }
+
+    /// <summary>
+    /// 验证码
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet("/challenge-captcha.jpg")]
+    [ResponseCache(NoStore = true, Duration = 0)]
+    public ActionResult CaptchaChallenge()
+    {
+        string code = ValidateCode.CreateValidateCode(6);
+        HttpContext.Session.Set("challenge-captcha", code);
+        var buffer = HttpContext.CreateValidateGraphic(code);
+        return this.ResumeFile(buffer, ContentType.Jpeg, "验证码.jpg");
+    }
+
+    /// <summary>
+    /// 反爬虫检测
+    /// </summary>
+    /// <param name="id"></param>
+    /// <param name="cacheManager"></param>
+    /// <param name="env"></param>
+    /// <returns></returns>
+    [HttpGet("/craw/{id}")]
+    public async Task<IActionResult> AntiCrawler(string id, [FromServices] ICacheManager<int> cacheManager, [FromServices] IWebHostEnvironment env)
+    {
+        if (Request.IsRobot())
         {
-            string code = ValidateCode.CreateValidateCode(6);
-            HttpContext.Session.Set("challenge-captcha", code);
-            var buffer = HttpContext.CreateValidateGraphic(code);
-            return this.ResumeFile(buffer, ContentType.Jpeg, "验证码.jpg");
+            return Ok();
         }
 
-        /// <summary>
-        /// 反爬虫检测
-        /// </summary>
-        /// <param name="id"></param>
-        /// <param name="cacheManager"></param>
-        /// <param name="env"></param>
-        /// <returns></returns>
-        [HttpGet("/craw/{id}")]
-        public async Task<IActionResult> AntiCrawler(string id, [FromServices] ICacheManager<int> cacheManager, [FromServices] IWebHostEnvironment env)
+        var ip = HttpContext.Connection.RemoteIpAddress.ToString();
+        await RedisHelper.LPushAsync("intercept", new IpIntercepter()
         {
-            if (Request.IsRobot())
+            IP = ip,
+            RequestUrl = HttpUtility.UrlDecode(Request.Scheme + "://" + Request.Host + "/craw/" + id),
+            Time = DateTime.Now,
+            Referer = Request.Headers[HeaderNames.Referer],
+            UserAgent = Request.Headers[HeaderNames.UserAgent],
+            Remark = "检测到异常爬虫行为",
+            Address = Request.Location(),
+            HttpVersion = Request.Protocol,
+            Headers = new
             {
-                return Ok();
-            }
-
-            var ip = HttpContext.Connection.RemoteIpAddress.ToString();
-            await RedisHelper.LPushAsync("intercept", new IpIntercepter()
-            {
-                IP = ip,
-                RequestUrl = HttpUtility.UrlDecode(Request.Scheme + "://" + Request.Host + "/craw/" + id),
-                Time = DateTime.Now,
-                Referer = Request.Headers[HeaderNames.Referer],
-                UserAgent = Request.Headers[HeaderNames.UserAgent],
-                Remark = "检测到异常爬虫行为",
-                Address = Request.Location(),
-                HttpVersion = Request.Protocol,
-                Headers = new
-                {
-                    Request.Protocol,
-                    Request.Headers
-                }.ToJsonString()
-            });
-            cacheManager.AddOrUpdate("AntiCrawler:" + ip, 1, i => i + 1, 5);
-            cacheManager.Expire("AntiCrawler:" + ip, ExpirationMode.Sliding, TimeSpan.FromMinutes(10));
-            var sitemap = Path.Combine(env.WebRootPath, "sitemap.txt");
-            return System.IO.File.Exists(sitemap) ? Redirect(System.IO.File.ReadLines(sitemap).OrderByRandom().FirstOrDefault() ?? "/") : Redirect("/");
+                Request.Protocol,
+                Request.Headers
+            }.ToJsonString()
+        });
+        cacheManager.AddOrUpdate("AntiCrawler:" + ip, 1, i => i + 1, 5);
+        cacheManager.Expire("AntiCrawler:" + ip, ExpirationMode.Sliding, TimeSpan.FromMinutes(10));
+        if (cacheManager.Get<int>("AntiCrawler:" + ip) > 3)
+        {
+            Response.StatusCode = 429;
+            return Content("");
         }
+
+        var sitemap = Path.Combine(env.WebRootPath, "sitemap.txt");
+        return System.IO.File.Exists(sitemap) ? Redirect(System.IO.File.ReadLines(sitemap).OrderByRandom().FirstOrDefault() ?? "/") : Redirect("/");
     }
 }

+ 160 - 161
src/Masuit.MyBlogs.Core/Extensions/Firewall/FirewallAttribute.cs

@@ -17,203 +17,202 @@ using System.Text.RegularExpressions;
 using System.Web;
 using HeaderNames = Microsoft.Net.Http.Headers.HeaderNames;
 
-namespace Masuit.MyBlogs.Core.Extensions.Firewall
+namespace Masuit.MyBlogs.Core.Extensions.Firewall;
+
+public class FirewallAttribute : IAsyncActionFilter
 {
-    public class FirewallAttribute : IAsyncActionFilter
-    {
-        public ICacheManager<int> CacheManager { get; set; }
+    public ICacheManager<int> CacheManager { get; set; }
+
+    public IFirewallRepoter FirewallRepoter { get; set; }
 
-        public IFirewallRepoter FirewallRepoter { get; set; }
+    public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
+    {
+        var request = context.HttpContext.Request;
+        var ip = context.HttpContext.Connection.RemoteIpAddress.ToString();
+        var tokenValid = request.Cookies["Email"].MDString3(AppConfig.BaiduAK).Equals(request.Cookies["FullAccessToken"]);
 
-        public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
+        //黑名单
+        if (ip.IsDenyIpAddress() && !tokenValid)
         {
-            var request = context.HttpContext.Request;
-            var ip = context.HttpContext.Connection.RemoteIpAddress.ToString();
-            var tokenValid = request.Cookies["Email"].MDString3(AppConfig.BaiduAK).Equals(request.Cookies["FullAccessToken"]);
+            AccessDeny(ip, request, "黑名单IP地址");
+            context.Result = new BadRequestObjectResult("您当前所在的网络环境不支持访问本站!");
+            return Task.CompletedTask;
+        }
 
-            //黑名单
-            if (ip.IsDenyIpAddress() && !tokenValid)
-            {
-                AccessDeny(ip, request, "黑名单IP地址");
-                context.Result = new BadRequestObjectResult("您当前所在的网络环境不支持访问本站!");
-                return Task.CompletedTask;
-            }
+        //bypass
+        if (CommonHelper.SystemSettings.GetOrAdd("FirewallEnabled", "true") == "false" || context.ActionDescriptor.EndpointMetadata.Any(o => o is MyAuthorizeAttribute or AllowAccessFirewallAttribute) || tokenValid)
+        {
+            return next();
+        }
 
-            //bypass
-            if (CommonHelper.SystemSettings.GetOrAdd("FirewallEnabled", "true") == "false" || context.ActionDescriptor.EndpointMetadata.Any(o => o is MyAuthorizeAttribute or AllowAccessFirewallAttribute) || tokenValid)
-            {
-                return next();
-            }
+        //UserAgent
+        var ua = request.Headers[HeaderNames.UserAgent] + "";
+        var blocked = CommonHelper.SystemSettings.GetOrAdd("UserAgentBlocked", "").Split(new[] { ',', '|' }, StringSplitOptions.RemoveEmptyEntries);
+        if (ua.Contains(blocked))
+        {
+            var agent = UserAgent.Parse(ua);
+            AccessDeny(ip, request, $"UA黑名单({agent.Browser} {agent.BrowserVersion}/{agent.Platform})");
+            var msg = CommonHelper.SystemSettings.GetOrAdd("UserAgentBlockedMsg", "当前浏览器不支持访问本站");
+            context.Result = new ContentResult()
+            {
+                Content = Template.Create(msg).Set("browser", agent.Browser + " " + agent.BrowserVersion).Set("os", agent.Platform).Render(),
+                ContentType = ContentType.Html + "; charset=utf-8",
+                StatusCode = 403
+            };
+            return Task.CompletedTask;
+        }
 
-            //UserAgent
-            var ua = request.Headers[HeaderNames.UserAgent] + "";
-            var blocked = CommonHelper.SystemSettings.GetOrAdd("UserAgentBlocked", "").Split(new[] { ',', '|' }, StringSplitOptions.RemoveEmptyEntries);
-            if (ua.Contains(blocked))
-            {
-                var agent = UserAgent.Parse(ua);
-                AccessDeny(ip, request, $"UA黑名单({agent.Browser} {agent.BrowserVersion}/{agent.Platform})");
-                var msg = CommonHelper.SystemSettings.GetOrAdd("UserAgentBlockedMsg", "当前浏览器不支持访问本站");
-                context.Result = new ContentResult()
-                {
-                    Content = Template.Create(msg).Set("browser", agent.Browser + " " + agent.BrowserVersion).Set("os", agent.Platform).Render(),
-                    ContentType = ContentType.Html + "; charset=utf-8",
-                    StatusCode = 403
-                };
-                return Task.CompletedTask;
-            }
+        //搜索引擎
+        if (Regex.IsMatch(request.Method, "OPTIONS|HEAD", RegexOptions.IgnoreCase) || request.IsRobot())
+        {
+            return next();
+        }
 
-            //搜索引擎
-            if (Regex.IsMatch(request.Method, "OPTIONS|HEAD", RegexOptions.IgnoreCase) || request.IsRobot())
+        // 反爬虫
+        if (CacheManager.GetOrAdd(nameof(FirewallController.AntiCrawler) + ":" + ip, 0) > 3)
+        {
+            context.Result = new ContentResult
             {
-                return next();
-            }
+                ContentType = ContentType.Html + "; charset=utf-8",
+                StatusCode = 429,
+                Content = "检测到访问异常,请在10分钟后再试!"
+            };
+            return Task.CompletedTask;
+        }
 
-            // 反爬虫
-            if (CacheManager.GetOrAdd(nameof(FirewallController.AntiCrawler) + ":" + ip, 0) > 3)
+        //安全模式
+        if (request.Query[SessionKey.SafeMode].Count > 0)
+        {
+            request.Cookies.TryGetValue(SessionKey.HideCategories, out var s);
+            context.HttpContext.Response.Cookies.Append(SessionKey.HideCategories, request.Query[SessionKey.SafeMode] + "," + s, new CookieOptions
             {
-                context.Result = new ContentResult
-                {
-                    ContentType = ContentType.Html + "; charset=utf-8",
-                    StatusCode = 429,
-                    Content = "检测到访问异常,请在10分钟后再试!"
-                };
-                return Task.CompletedTask;
-            }
+                Expires = DateTime.Now.AddYears(1),
+                SameSite = SameSiteMode.Lax
+            });
+        }
 
-            //安全模式
-            if (request.Query[SessionKey.SafeMode].Count > 0)
-            {
-                request.Cookies.TryGetValue(SessionKey.HideCategories, out var s);
-                context.HttpContext.Response.Cookies.Append(SessionKey.HideCategories, request.Query[SessionKey.SafeMode] + "," + s, new CookieOptions
-                {
-                    Expires = DateTime.Now.AddYears(1),
-                    SameSite = SameSiteMode.Lax
-                });
-            }
+        //白名单地区
+        var (location, network, pos) = ip.GetIPLocation();
+        var allowedAreas = CommonHelper.SystemSettings.GetOrAdd("AllowedArea", "").Split(new[] { ',', ',' }, StringSplitOptions.RemoveEmptyEntries);
+        if (allowedAreas.Any() && pos.Contains(allowedAreas))
+        {
+            return next();
+        }
 
-            //白名单地区
-            var (location, network, pos) = ip.GetIPLocation();
-            var allowedAreas = CommonHelper.SystemSettings.GetOrAdd("AllowedArea", "").Split(new[] { ',', ',' }, StringSplitOptions.RemoveEmptyEntries);
-            if (allowedAreas.Any() && pos.Contains(allowedAreas))
+        //黑名单地区
+        var denyAreas = CommonHelper.SystemSettings.GetOrAdd("DenyArea", "").Split(new[] { ',', ',' }, StringSplitOptions.RemoveEmptyEntries);
+        if (denyAreas.Any())
+        {
+            if (string.IsNullOrWhiteSpace(location) || string.IsNullOrWhiteSpace(network) || pos.Contains(denyAreas) || denyAreas.Intersect(pos.Split("|")).Any()) // 未知地区的,未知网络的,禁区的
             {
-                return next();
+                AccessDeny(ip, request, "访问地区限制");
+                throw new AccessDenyException("访问地区限制");
             }
+        }
 
-            //黑名单地区
-            var denyAreas = CommonHelper.SystemSettings.GetOrAdd("DenyArea", "").Split(new[] { ',', ',' }, StringSplitOptions.RemoveEmptyEntries);
-            if (denyAreas.Any())
-            {
-                if (string.IsNullOrWhiteSpace(location) || string.IsNullOrWhiteSpace(network) || pos.Contains(denyAreas) || denyAreas.Intersect(pos.Split("|")).Any()) // 未知地区的,未知网络的,禁区的
-                {
-                    AccessDeny(ip, request, "访问地区限制");
-                    throw new AccessDenyException("访问地区限制");
-                }
-            }
+        //挑战模式
+        if (context.HttpContext.Session.TryGetValue("js-challenge", out _) || request.Path.ToUriComponent().Contains("."))
+        {
+            return next();
+        }
 
-            //挑战模式
-            if (context.HttpContext.Session.TryGetValue("js-challenge", out _) || request.Path.ToUriComponent().Contains("."))
+        try
+        {
+            if (request.Cookies.TryGetValue(SessionKey.ChallengeBypass, out var time) && time.AESDecrypt(AppConfig.BaiduAK).ToDateTime() > DateTime.Now)
             {
+                context.HttpContext.Session.Set("js-challenge", 1);
                 return next();
             }
-
-            try
-            {
-                if (request.Cookies.TryGetValue(SessionKey.ChallengeBypass, out var time) && time.AESDecrypt(AppConfig.BaiduAK).ToDateTime() > DateTime.Now)
-                {
-                    context.HttpContext.Session.Set("js-challenge", 1);
-                    return next();
-                }
-            }
-            catch
-            {
-                context.HttpContext.Response.Cookies.Delete(SessionKey.ChallengeBypass);
-            }
-
-            if (Challenge(context, out var completedTask))
-            {
-                return completedTask;
-            }
-
-            //限流
-            return ThrottleLimit(ip, request, next);
+        }
+        catch
+        {
+            context.HttpContext.Response.Cookies.Delete(SessionKey.ChallengeBypass);
         }
 
-        private static bool Challenge(ActionExecutingContext context, out Task completedTask)
+        if (Challenge(context, out var completedTask))
         {
-            var mode = CommonHelper.SystemSettings.GetOrAdd(SessionKey.ChallengeMode, "");
-            if (mode == SessionKey.JSChallenge)
-            {
-                context.Result = new ViewResult()
-                {
-                    ViewName = "/Views/Shared/JSChallenge.cshtml"
-                };
-                completedTask = Task.CompletedTask;
-                return true;
-            }
+            return completedTask;
+        }
 
-            if (mode == SessionKey.CaptchaChallenge)
-            {
-                context.Result = new ViewResult()
-                {
-                    ViewName = "/Views/Shared/CaptchaChallenge.cshtml"
-                };
-                completedTask = Task.CompletedTask;
-                return true;
-            }
+        //限流
+        return ThrottleLimit(ip, request, next);
+    }
 
+    private static bool Challenge(ActionExecutingContext context, out Task completedTask)
+    {
+        var mode = CommonHelper.SystemSettings.GetOrAdd(SessionKey.ChallengeMode, "");
+        if (mode == SessionKey.JSChallenge)
+        {
+            context.Result = new ViewResult()
+            {
+                ViewName = "/Views/Shared/JSChallenge.cshtml"
+            };
             completedTask = Task.CompletedTask;
-            return false;
+            return true;
         }
 
-        private Task ThrottleLimit(string ip, HttpRequest request, ActionExecutionDelegate next)
+        if (mode == SessionKey.CaptchaChallenge)
         {
-            var times = CacheManager.AddOrUpdate("Frequency:" + ip, 1, i => i + 1, 5);
-            CacheManager.Expire("Frequency:" + ip, ExpirationMode.Absolute, TimeSpan.FromSeconds(CommonHelper.SystemSettings.GetOrAdd("LimitIPFrequency", "60").ToInt32()));
-            var limit = CommonHelper.SystemSettings.GetOrAdd("LimitIPRequestTimes", "90").ToInt32();
-            if (times <= limit)
+            context.Result = new ViewResult()
             {
-                return next();
-            }
+                ViewName = "/Views/Shared/CaptchaChallenge.cshtml"
+            };
+            completedTask = Task.CompletedTask;
+            return true;
+        }
 
-            if (times > limit * 1.2)
-            {
-                CacheManager.Expire("Frequency:" + ip, TimeSpan.FromMinutes(CommonHelper.SystemSettings.GetOrAdd("BanIPTimespan", "10").ToInt32()));
-                AccessDeny(ip, request, "访问频次限制");
-                throw new TempDenyException("访问频次限制");
-            }
+        completedTask = Task.CompletedTask;
+        return false;
+    }
 
+    private Task ThrottleLimit(string ip, HttpRequest request, ActionExecutionDelegate next)
+    {
+        var times = CacheManager.AddOrUpdate("Frequency:" + ip, 1, i => i + 1, 5);
+        CacheManager.Expire("Frequency:" + ip, ExpirationMode.Absolute, TimeSpan.FromSeconds(CommonHelper.SystemSettings.GetOrAdd("LimitIPFrequency", "60").ToInt32()));
+        var limit = CommonHelper.SystemSettings.GetOrAdd("LimitIPRequestTimes", "90").ToInt32();
+        if (times <= limit)
+        {
             return next();
         }
 
-        private async void AccessDeny(string ip, HttpRequest request, string remark)
+        if (times > limit * 1.2)
         {
-            var path = HttpUtility.UrlDecode(request.Path + request.QueryString, Encoding.UTF8);
-            await RedisHelper.IncrByAsync("interceptCount");
-            await RedisHelper.LPushAsync("intercept", new IpIntercepter()
-            {
-                IP = ip,
-                RequestUrl = HttpUtility.UrlDecode(request.Scheme + "://" + request.Host + path),
-                Time = DateTime.Now,
-                Referer = request.Headers[HeaderNames.Referer],
-                UserAgent = request.Headers[HeaderNames.UserAgent],
-                Remark = remark,
-                Address = request.Location(),
-                HttpVersion = request.Protocol,
-                Headers = new
-                {
-                    request.Protocol,
-                    request.Headers
-                }.ToJsonString()
-            });
-            var limit = CommonHelper.SystemSettings.GetOrAdd("LimitIPInterceptTimes", "30").ToInt32();
-            await RedisHelper.LRangeAsync<IpIntercepter>("intercept", 0, -1).ContinueWith(async t =>
-            {
-                if (t.Result.Count(x => x.IP == ip) >= limit)
-                {
-                    LogManager.Info($"准备上报IP{ip}到{FirewallRepoter.ReporterName}");
-                    await FirewallRepoter.ReportAsync(IPAddress.Parse(ip)).ContinueWith(_ => LogManager.Info($"访问频次限制,已上报IP{ip}至:" + FirewallRepoter.ReporterName));
-                }
-            });
+            CacheManager.Expire("Frequency:" + ip, TimeSpan.FromMinutes(CommonHelper.SystemSettings.GetOrAdd("BanIPTimespan", "10").ToInt32()));
+            AccessDeny(ip, request, "访问频次限制");
+            throw new TempDenyException("访问频次限制");
         }
+
+        return next();
+    }
+
+    private async void AccessDeny(string ip, HttpRequest request, string remark)
+    {
+        var path = HttpUtility.UrlDecode(request.Path + request.QueryString, Encoding.UTF8);
+        await RedisHelper.IncrByAsync("interceptCount");
+        await RedisHelper.LPushAsync("intercept", new IpIntercepter()
+        {
+            IP = ip,
+            RequestUrl = HttpUtility.UrlDecode(request.Scheme + "://" + request.Host + path),
+            Time = DateTime.Now,
+            Referer = request.Headers[HeaderNames.Referer],
+            UserAgent = request.Headers[HeaderNames.UserAgent],
+            Remark = remark,
+            Address = request.Location(),
+            HttpVersion = request.Protocol,
+            Headers = new
+            {
+                request.Protocol,
+                request.Headers
+            }.ToJsonString()
+        });
+        var limit = CommonHelper.SystemSettings.GetOrAdd("LimitIPInterceptTimes", "30").ToInt32();
+        await RedisHelper.LRangeAsync<IpIntercepter>("intercept", 0, -1).ContinueWith(async t =>
+        {
+            if (t.Result.Count(x => x.IP == ip) >= limit)
+            {
+                LogManager.Info($"准备上报IP{ip}到{FirewallRepoter.ReporterName}");
+                await FirewallRepoter.ReportAsync(IPAddress.Parse(ip)).ContinueWith(_ => LogManager.Info($"访问频次限制,已上报IP{ip}至:" + FirewallRepoter.ReporterName));
+            }
+        });
     }
 }

+ 0 - 2
src/Masuit.MyBlogs.Core/Infrastructure/LoggerDbContext.cs

@@ -3,8 +3,6 @@ using Microsoft.EntityFrameworkCore;
 using System.Reflection;
 using Masuit.MyBlogs.Core.Common;
 using Microsoft.EntityFrameworkCore.Metadata;
-using Lucene.Net.Sandbox.Queries;
-using OpenXmlPowerTools;
 
 namespace Masuit.MyBlogs.Core.Infrastructure;
 

+ 8 - 8
src/Masuit.MyBlogs.Core/Masuit.MyBlogs.Core.csproj

@@ -54,15 +54,15 @@
         <PackageReference Include="htmldiff.net-core" Version="1.3.6" />
         <PackageReference Include="IP2Region" Version="1.2.0" />
         <PackageReference Include="Karambolo.AspNetCore.Bundling.NUglify" Version="3.5.1" />
-        <PackageReference Include="Magick.NET-Q8-AnyCPU" Version="11.2.1" />
+        <PackageReference Include="Magick.NET-Q8-AnyCPU" Version="11.3.0" />
         <PackageReference Include="Masuit.Tools.Excel" Version="1.2.2" />
         <PackageReference Include="MaxMind.GeoIP2" Version="5.1.0" />
-        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.6" />
-        <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.6" />
-        <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="6.0.6" />
-        <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.6" />
-        <PackageReference Include="Microsoft.Extensions.Http.Polly" Version="6.0.6" />
-        <PackageReference Include="Microsoft.Graph" Version="4.34.0" />
+        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.7" />
+        <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.7" />
+        <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="6.0.7" />
+        <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.7" />
+        <PackageReference Include="Microsoft.Extensions.Http.Polly" Version="6.0.7" />
+        <PackageReference Include="Microsoft.Graph" Version="4.35.0" />
         <PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.7" />
         <PackageReference Include="MiniProfiler.AspNetCore.Mvc" Version="4.2.22" />
         <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.5" />
@@ -74,7 +74,7 @@
         <PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.19" />
         <PackageReference Include="TimeZoneConverter" Version="5.0.0" />
         <PackageReference Include="WilderMinds.RssSyndication" Version="1.7.0" />
-        <PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="6.14.2" />
+        <PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="6.14.3" />
     </ItemGroup>
     <ItemGroup>
         <Content Update="appsettings.json">

+ 1 - 1
src/Masuit.MyBlogs.Core/Program.cs

@@ -55,7 +55,7 @@ static void InitOneDrive()
     //初始化
     if (!File.Exists(Path.Combine(Directory.GetCurrentDirectory(), "App_Data", "OneDrive.db")))
     {
-        File.Copy(Path.Combine("App_Data","OneDrive.template.db"), Path.Combine("App_Data","OneDrive.db"));
+        File.Copy(Path.Combine("App_Data", "OneDrive.template.db"), Path.Combine("App_Data", "OneDrive.db"));
         Console.WriteLine("数据库创建成功");
     }
 

+ 2 - 0
src/Masuit.MyBlogs.Core/Startup.cs

@@ -30,6 +30,7 @@ using SixLabors.ImageSharp.Web.Processors;
 using SixLabors.ImageSharp.Web.Providers;
 using System.Net;
 using System.Text.RegularExpressions;
+using Masuit.Tools.AspNetCore.Extensions;
 using Microsoft.IO;
 
 namespace Masuit.MyBlogs.Core
@@ -165,6 +166,7 @@ namespace Masuit.MyBlogs.Core
             services.SetupMiniProfile();
             services.AddSingleton<IMimeMapper, MimeMapper>(p => new MimeMapper());
             services.AddOneDrive();
+            services.AutoRegisterServices();
             services.AddRazorPages();
             services.AddServerSideBlazor();
             services.AddMapper().AddMyMvc();