FirewallAttribute.cs 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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.Core.Net;
  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. if (!bool.Parse(CommonHelper.SystemSettings.GetOrAdd("FirewallEnabled", "true")) || context.Filters.Any(m => m.ToString().Contains(nameof(AllowAccessFirewallAttribute))) || request.Cookies["Email"].MDString3(AppConfig.BaiduAK).Equals(request.Cookies["FullAccessToken"]))
  27. {
  28. return;
  29. }
  30. var ip = context.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
  31. var sessionToken = context.HttpContext.Session.Get<string>("FullAccessViewToken");
  32. if (ip.IsDenyIpAddress() && string.IsNullOrEmpty(sessionToken))
  33. {
  34. AccessDeny(context, ip, request);
  35. context.Result = new BadRequestObjectResult("您当前所在的网络环境不支持访问本站!");
  36. return;
  37. }
  38. if (ip.IsInDenyArea() && string.IsNullOrEmpty(sessionToken))
  39. {
  40. AccessDeny(context, 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(context, ip, request);
  59. }
  60. context.Result = new RedirectResult("/tempdeny");
  61. }
  62. private void AccessDeny(ActionExecutingContext context, string ip, HttpRequest request)
  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. }));
  72. }
  73. }
  74. }