Răsfoiți Sursa

Merge pull request #5755 from BaronGreenback/NetworkAccessPolicy

Claus Vium 3 ani în urmă
părinte
comite
deb349f4c5

+ 47 - 0
Jellyfin.Api/Auth/AnonymousLanAccessPolicy/AnonymousLanAccessHandler.cs

@@ -0,0 +1,47 @@
+using System.Threading.Tasks;
+using MediaBrowser.Common.Net;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+
+namespace Jellyfin.Api.Auth.AnonymousLanAccessPolicy
+{
+    /// <summary>
+    /// LAN access handler. Allows anonymous users.
+    /// </summary>
+    public class AnonymousLanAccessHandler : AuthorizationHandler<AnonymousLanAccessRequirement>
+    {
+        private readonly INetworkManager _networkManager;
+        private readonly IHttpContextAccessor _httpContextAccessor;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="AnonymousLanAccessHandler"/> class.
+        /// </summary>
+        /// <param name="networkManager">Instance of the <see cref="INetworkManager"/> interface.</param>
+        /// <param name="httpContextAccessor">Instance of the <see cref="IHttpContextAccessor"/> interface.</param>
+        public AnonymousLanAccessHandler(
+            INetworkManager networkManager,
+            IHttpContextAccessor httpContextAccessor)
+        {
+            _networkManager = networkManager;
+            _httpContextAccessor = httpContextAccessor;
+        }
+
+        /// <inheritdoc />
+        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AnonymousLanAccessRequirement 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/AnonymousLanAccessPolicy/AnonymousLanAccessRequirement.cs

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

+ 1 - 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;

+ 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 (anonymous) LAN access.
+        /// </summary>
+        public const string AnonymousLanAccessPolicy = "AnonymousLanAccessPolicy";
+
         /// <summary>
         /// Policy name for escaping schedule controls or requiring first time setup.
         /// </summary>

+ 3 - 0
Jellyfin.Api/Controllers/DlnaServerController.cs

@@ -7,7 +7,9 @@ using System.Threading.Tasks;
 using Emby.Dlna;
 using Emby.Dlna.Main;
 using Jellyfin.Api.Attributes;
+using Jellyfin.Api.Constants;
 using MediaBrowser.Controller.Dlna;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 
@@ -17,6 +19,7 @@ namespace Jellyfin.Api.Controllers
     /// Dlna Server Controller.
     /// </summary>
     [Route("Dlna")]
+    [Authorize(Policy = Policies.AnonymousLanAccessPolicy)]
     public class DlnaServerController : BaseJellyfinApiController
     {
         private readonly IDlnaManager _dlnaManager;

+ 9 - 0
Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs

@@ -7,6 +7,7 @@ using System.Net.Sockets;
 using System.Reflection;
 using Emby.Server.Implementations;
 using Jellyfin.Api.Auth;
+using Jellyfin.Api.Auth.AnonymousLanAccessPolicy;
 using Jellyfin.Api.Auth.DefaultAuthorizationPolicy;
 using Jellyfin.Api.Auth.DownloadPolicy;
 using Jellyfin.Api.Auth.FirstTimeOrIgnoreParentalControlSetupPolicy;
@@ -61,6 +62,7 @@ namespace Jellyfin.Server.Extensions
             serviceCollection.AddSingleton<IAuthorizationHandler, IgnoreParentalControlHandler>();
             serviceCollection.AddSingleton<IAuthorizationHandler, FirstTimeOrIgnoreParentalControlSetupHandler>();
             serviceCollection.AddSingleton<IAuthorizationHandler, LocalAccessHandler>();
+            serviceCollection.AddSingleton<IAuthorizationHandler, AnonymousLanAccessHandler>();
             serviceCollection.AddSingleton<IAuthorizationHandler, LocalAccessOrRequiresElevationHandler>();
             serviceCollection.AddSingleton<IAuthorizationHandler, RequiresElevationHandler>();
             serviceCollection.AddSingleton<IAuthorizationHandler, SyncPlayAccessHandler>();
@@ -157,6 +159,13 @@ namespace Jellyfin.Server.Extensions
                         policy.AddAuthenticationSchemes(AuthenticationSchemes.CustomAuthentication);
                         policy.AddRequirements(new SyncPlayAccessRequirement(SyncPlayAccessRequirementType.IsInGroup));
                     });
+                options.AddPolicy(
+                    Policies.AnonymousLanAccessPolicy,
+                    policy =>
+                    {
+                        policy.AddAuthenticationSchemes(AuthenticationSchemes.CustomAuthentication);
+                        policy.AddRequirements(new AnonymousLanAccessRequirement());
+                    });
             });
         }