IpBasedAccessValidationMiddleware.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using System.Net;
  2. using System.Threading.Tasks;
  3. using System.Web;
  4. using MediaBrowser.Common.Extensions;
  5. using MediaBrowser.Common.Net;
  6. using Microsoft.AspNetCore.Http;
  7. using Microsoft.Extensions.Logging;
  8. namespace Jellyfin.Api.Middleware;
  9. /// <summary>
  10. /// Validates the IP of requests coming from local networks wrt. remote access.
  11. /// </summary>
  12. public class IPBasedAccessValidationMiddleware
  13. {
  14. private readonly RequestDelegate _next;
  15. private readonly ILogger<IPBasedAccessValidationMiddleware> _logger;
  16. /// <summary>
  17. /// Initializes a new instance of the <see cref="IPBasedAccessValidationMiddleware"/> class.
  18. /// </summary>
  19. /// <param name="next">The next delegate in the pipeline.</param>
  20. /// <param name="logger">The logger to log to.</param>
  21. public IPBasedAccessValidationMiddleware(RequestDelegate next, ILogger<IPBasedAccessValidationMiddleware> logger)
  22. {
  23. _next = next;
  24. _logger = logger;
  25. }
  26. /// <summary>
  27. /// Executes the middleware action.
  28. /// </summary>
  29. /// <param name="httpContext">The current HTTP context.</param>
  30. /// <param name="networkManager">The network manager.</param>
  31. /// <returns>The async task.</returns>
  32. public async Task Invoke(HttpContext httpContext, INetworkManager networkManager)
  33. {
  34. if (httpContext.IsLocal())
  35. {
  36. // Accessing from the same machine as the server.
  37. await _next(httpContext).ConfigureAwait(false);
  38. return;
  39. }
  40. var remoteIP = httpContext.GetNormalizedRemoteIP();
  41. var result = networkManager.ShouldAllowServerAccess(remoteIP);
  42. if (result != RemoteAccessPolicyResult.Allow)
  43. {
  44. // No access from network, respond with 503 instead of 200.
  45. _logger.LogWarning(
  46. "Blocking request to {Path} by {RemoteIP} due to IP filtering rule, reason: {Reason}",
  47. // url-encode to block log injection
  48. HttpUtility.UrlEncode(httpContext.Request.Path),
  49. remoteIP,
  50. result);
  51. httpContext.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;
  52. return;
  53. }
  54. await _next(httpContext).ConfigureAwait(false);
  55. }
  56. }