FirewallAttribute.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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.AspNetCore.Mime;
  8. using Masuit.Tools.Security;
  9. using Microsoft.AspNetCore.Http;
  10. using Microsoft.AspNetCore.Mvc;
  11. using Microsoft.AspNetCore.Mvc.Filters;
  12. using System;
  13. using System.Linq;
  14. using System.Text;
  15. using System.Text.RegularExpressions;
  16. using System.Web;
  17. using HeaderNames = Microsoft.Net.Http.Headers.HeaderNames;
  18. namespace Masuit.MyBlogs.Core.Extensions
  19. {
  20. public class FirewallAttribute : ActionFilterAttribute
  21. {
  22. public ICacheManager<int> CacheManager { get; set; }
  23. /// <inheritdoc />
  24. public override void OnActionExecuting(ActionExecutingContext context)
  25. {
  26. var request = context.HttpContext.Request;
  27. var ip = context.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
  28. var trueip = request.Headers[AppConfig.TrueClientIPHeader].ToString();
  29. if (!string.IsNullOrEmpty(trueip) && ip != trueip)
  30. {
  31. AccessDeny(trueip, request, "客户端请求不合法,伪造IP:" + ip);
  32. context.Result = new BadRequestObjectResult("当前请求已被非法篡改,本站阻止访问!如果你不知道发生了什么,请尝试关闭如adguard隐身模式、代理软件、可能会修改http请求的浏览器扩展等再进行重试!");
  33. return;
  34. }
  35. var tokenValid = request.Cookies["Email"].MDString3(AppConfig.BaiduAK).Equals(request.Cookies["FullAccessToken"]);
  36. if (ip.IsDenyIpAddress() && !tokenValid)
  37. {
  38. AccessDeny(ip, request, "黑名单IP地址");
  39. context.Result = new BadRequestObjectResult("您当前所在的网络环境不支持访问本站!");
  40. return;
  41. }
  42. if (CommonHelper.SystemSettings.GetOrAdd("FirewallEnabled", "true") == "false" || context.Filters.Any(m => m.ToString().Contains(nameof(AllowAccessFirewallAttribute))) || tokenValid)
  43. {
  44. return;
  45. }
  46. var ua = request.Headers[HeaderNames.UserAgent] + "";
  47. var blocked = CommonHelper.SystemSettings.GetOrAdd("UserAgentBlocked", "").Split(new[] { ',', '|' }, StringSplitOptions.RemoveEmptyEntries);
  48. if (ua.Contains(blocked))
  49. {
  50. AccessDeny(ip, request, "UA黑名单");
  51. context.Result = new ContentResult()
  52. {
  53. Content = CommonHelper.SystemSettings.GetOrAdd("UserAgentBlockedMsg", "当前浏览器不支持访问本站"),
  54. ContentType = ContentType.Html,
  55. StatusCode = 403
  56. };
  57. return;
  58. }
  59. if (ip.IsInDenyArea() && !tokenValid)
  60. {
  61. AccessDeny(ip, request, "访问地区限制");
  62. throw new AccessDenyException("访问地区限制");
  63. }
  64. if (Regex.IsMatch(request.Method, "OPTIONS|HEAD", RegexOptions.IgnoreCase) || request.IsRobot())
  65. {
  66. return;
  67. }
  68. var times = CacheManager.AddOrUpdate("Frequency:" + ip, 1, i => i + 1, 5);
  69. CacheManager.Expire("Frequency:" + ip, ExpirationMode.Sliding, TimeSpan.FromSeconds(CommonHelper.SystemSettings.GetOrAdd("LimitIPFrequency", "60").ToInt32()));
  70. var limit = CommonHelper.SystemSettings.GetOrAdd("LimitIPRequestTimes", "90").ToInt32();
  71. if (times <= limit)
  72. {
  73. return;
  74. }
  75. if (times > limit * 1.2)
  76. {
  77. CacheManager.Expire("Frequency:" + ip, ExpirationMode.Sliding, TimeSpan.FromMinutes(CommonHelper.SystemSettings.GetOrAdd("BanIPTimespan", "10").ToInt32()));
  78. AccessDeny(ip, request, "访问频次限制");
  79. }
  80. throw new TempDenyException("访问地区限制");
  81. }
  82. private void AccessDeny(string ip, HttpRequest request, string remark)
  83. {
  84. var path = HttpUtility.UrlDecode(request.Path + request.QueryString, Encoding.UTF8);
  85. BackgroundJob.Enqueue(() => HangfireBackJob.InterceptLog(new IpIntercepter()
  86. {
  87. IP = ip,
  88. RequestUrl = HttpUtility.UrlDecode(request.Scheme + "://" + request.Host + path),
  89. Time = DateTime.Now,
  90. UserAgent = request.Headers[HeaderNames.UserAgent],
  91. Remark = remark
  92. }));
  93. }
  94. }
  95. }