Procházet zdrojové kódy

Network Access Policy

BaronGreenback před 4 roky
rodič
revize
5fb7557763

+ 11 - 1
Jellyfin.Api/Auth/BaseAuthorizationHandler.cs

@@ -1,4 +1,4 @@
-using System.Security.Claims;
+using System.Security.Claims;
 using Jellyfin.Api.Helpers;
 using Jellyfin.Data.Enums;
 using MediaBrowser.Common.Extensions;
@@ -36,6 +36,16 @@ namespace Jellyfin.Api.Auth
             _httpContextAccessor = httpContextAccessor;
         }
 
+        /// <summary>
+        /// Gets a value indicating <see cref="INetworkManager"/> being used.
+        /// </summary>
+        protected INetworkManager NetworkManager => _networkManager;
+
+        /// <summary>
+        /// Gets a value indicating the <see cref="HttpContextAccessor"/> being used.
+        /// </summary>
+        protected IHttpContextAccessor HttpContextAccessor => _httpContextAccessor;
+
         /// <summary>
         /// Validate authenticated claims.
         /// </summary>

+ 48 - 0
Jellyfin.Api/Auth/NetworkAccessPolicy/NetworkAccessHandler.cs

@@ -0,0 +1,48 @@
+using System.Threading.Tasks;
+using Jellyfin.Api.Auth;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Library;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+
+namespace Jellyfin.Api.Auth.NetworkAccessPolicy
+{
+    /// <summary>
+    /// Local access handler.
+    /// </summary>
+    public class NetworkAccessHandler : BaseAuthorizationHandler<NetworkAccessRequirement>
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="NetworkAccessHandler"/> class.
+        /// </summary>
+        /// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
+        /// <param name="networkManager">Instance of the <see cref="INetworkManager"/> interface.</param>
+        /// <param name="httpContextAccessor">Instance of the <see cref="IHttpContextAccessor"/> interface.</param>
+        public NetworkAccessHandler(
+            IUserManager userManager,
+            INetworkManager networkManager,
+            IHttpContextAccessor httpContextAccessor)
+            : base(userManager, networkManager, httpContextAccessor)
+        {
+        }
+
+        /// <inheritdoc />
+        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, NetworkAccessRequirement requirement)
+        {
+            var ip = HttpContextAccessor.HttpContext?.Connection.RemoteIpAddress;
+
+            // Loopback will be on LAN, so we can accept null.
+            if (ip == null || NetworkManager.IsInLocalNetwork(ip))
+            {
+                context.Succeed(requirement);
+            }
+            else
+            {
+                context.Fail();
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+}

+ 11 - 0
Jellyfin.Api/Auth/NetworkAccessPolicy/NetworkAccessRequirement.cs

@@ -0,0 +1,11 @@
+using Microsoft.AspNetCore.Authorization;
+
+namespace Jellyfin.Api.Auth.NetworkAccessPolicy
+{
+    /// <summary>
+    /// The local network authorization requirement.
+    /// </summary>
+    public class NetworkAccessRequirement : IAuthorizationRequirement
+    {
+    }
+}

+ 5 - 0
Jellyfin.Api/Constants/Policies.cs

@@ -45,6 +45,11 @@ namespace Jellyfin.Api.Constants
         /// </summary>
         public const string LocalAccessOrRequiresElevation = "LocalAccessOrRequiresElevation";
 
+        /// <summary>
+        /// Policy name for requiring local LAN access.
+        /// </summary>
+        public const string NetworkAccessPolicy = "NetworkAccessPolicy";
+
         /// <summary>
         /// Policy name for escaping schedule controls or requiring first time setup.
         /// </summary>

+ 10 - 1
Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs

@@ -15,6 +15,7 @@ using Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy;
 using Jellyfin.Api.Auth.IgnoreParentalControlPolicy;
 using Jellyfin.Api.Auth.LocalAccessOrRequiresElevationPolicy;
 using Jellyfin.Api.Auth.LocalAccessPolicy;
+using Jellyfin.Api.Auth.NetworkAccessPolicy;
 using Jellyfin.Api.Auth.RequiresElevationPolicy;
 using Jellyfin.Api.Auth.SyncPlayAccessPolicy;
 using Jellyfin.Api.Constants;
@@ -61,6 +62,7 @@ namespace Jellyfin.Server.Extensions
             serviceCollection.AddSingleton<IAuthorizationHandler, IgnoreParentalControlHandler>();
             serviceCollection.AddSingleton<IAuthorizationHandler, FirstTimeOrIgnoreParentalControlSetupHandler>();
             serviceCollection.AddSingleton<IAuthorizationHandler, LocalAccessHandler>();
+            serviceCollection.AddSingleton<IAuthorizationHandler, NetworkAccessHandler>();
             serviceCollection.AddSingleton<IAuthorizationHandler, LocalAccessOrRequiresElevationHandler>();
             serviceCollection.AddSingleton<IAuthorizationHandler, RequiresElevationHandler>();
             serviceCollection.AddSingleton<IAuthorizationHandler, SyncPlayAccessHandler>();
@@ -113,7 +115,7 @@ namespace Jellyfin.Server.Extensions
                     policy =>
                     {
                         policy.AddAuthenticationSchemes(AuthenticationSchemes.CustomAuthentication);
-                        policy.AddRequirements(new LocalAccessRequirement());
+                        policy.AddRequirements(new NetworkAccessRequirement());
                     });
                 options.AddPolicy(
                     Policies.LocalAccessOrRequiresElevation,
@@ -157,6 +159,13 @@ namespace Jellyfin.Server.Extensions
                         policy.AddAuthenticationSchemes(AuthenticationSchemes.CustomAuthentication);
                         policy.AddRequirements(new SyncPlayAccessRequirement(SyncPlayAccessRequirementType.IsInGroup));
                     });
+                options.AddPolicy(
+                    Policies.NetworkAccessPolicy,
+                    policy =>
+                    {
+                        policy.AddAuthenticationSchemes(AuthenticationSchemes.CustomAuthentication);
+                        policy.AddRequirements(new NetworkAccessRequirement());
+                    });
             });
         }