FirewallAttribute.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. using CacheManager.Core;
  2. using Hangfire;
  3. using Masuit.MyBlogs.Core.Common;
  4. using Masuit.MyBlogs.Core.Configs;
  5. using Masuit.MyBlogs.Core.Extensions.Hangfire;
  6. using Masuit.Tools;
  7. using Masuit.Tools.Security;
  8. using Microsoft.AspNetCore.Http;
  9. using Microsoft.AspNetCore.Mvc;
  10. using Microsoft.AspNetCore.Mvc.Filters;
  11. using Microsoft.Net.Http.Headers;
  12. using System;
  13. using System.Linq;
  14. using System.Text;
  15. using System.Text.RegularExpressions;
  16. using System.Web;
  17. namespace Masuit.MyBlogs.Core.Extensions
  18. {
  19. public class FirewallAttribute : ActionFilterAttribute
  20. {
  21. public ICacheManager<int> CacheManager { get; set; }
  22. /// <inheritdoc />
  23. public override void OnActionExecuting(ActionExecutingContext context)
  24. {
  25. var request = context.HttpContext.Request;
  26. var ip = context.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
  27. var tokenValid = request.Cookies["Email"].MDString3(AppConfig.BaiduAK).Equals(request.Cookies["FullAccessToken"]);
  28. if (ip.IsDenyIpAddress() && !tokenValid)
  29. {
  30. AccessDeny(ip, request, "黑名单IP地址");
  31. context.Result = new BadRequestObjectResult("您当前所在的网络环境不支持访问本站!");
  32. return;
  33. }
  34. if (CommonHelper.SystemSettings.GetOrAdd("FirewallEnabled", "true") == "false" || context.Filters.Any(m => m.ToString().Contains(nameof(AllowAccessFirewallAttribute))) || tokenValid)
  35. {
  36. return;
  37. }
  38. if (ip.IsInDenyArea() && !tokenValid)
  39. {
  40. AccessDeny(ip, request, "访问地区限制");
  41. context.Result = new RedirectToActionResult("AccessDeny", "Error", null);
  42. return;
  43. }
  44. if (Regex.IsMatch(request.Method, "OPTIONS|HEAD", RegexOptions.IgnoreCase) || request.IsRobot())
  45. {
  46. return;
  47. }
  48. var times = CacheManager.AddOrUpdate("Frequency:" + ip, 1, i => i + 1, 5);
  49. CacheManager.Expire("Frequency:" + ip, ExpirationMode.Sliding, TimeSpan.FromSeconds(CommonHelper.SystemSettings.GetOrAdd("LimitIPFrequency", "60").ToInt32()));
  50. var limit = CommonHelper.SystemSettings.GetOrAdd("LimitIPRequestTimes", "90").ToInt32();
  51. if (times <= limit)
  52. {
  53. return;
  54. }
  55. if (times > limit * 1.2)
  56. {
  57. CacheManager.Expire("Frequency:" + ip, ExpirationMode.Sliding, TimeSpan.FromMinutes(CommonHelper.SystemSettings.GetOrAdd("BanIPTimespan", "10").ToInt32()));
  58. AccessDeny(ip, request, "访问频次限制");
  59. }
  60. context.Result = new RedirectResult("/tempdeny");
  61. }
  62. private void AccessDeny(string ip, HttpRequest request, string remark)
  63. {
  64. var path = HttpUtility.UrlDecode(request.Path + request.QueryString, Encoding.UTF8);
  65. BackgroundJob.Enqueue(() => HangfireBackJob.InterceptLog(new IpIntercepter()
  66. {
  67. IP = ip,
  68. RequestUrl = HttpUtility.UrlDecode(request.Scheme + "://" + request.Host + path),
  69. Time = DateTime.Now,
  70. UserAgent = request.Headers[HeaderNames.UserAgent],
  71. Remark = remark
  72. }));
  73. }
  74. }
  75. }