aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jellyfin.Api/Auth/AnonymousLanAccessPolicy/AnonymousLanAccessHandler.cs47
-rw-r--r--Jellyfin.Api/Auth/AnonymousLanAccessPolicy/AnonymousLanAccessRequirement.cs11
-rw-r--r--Jellyfin.Api/Auth/BaseAuthorizationHandler.cs2
-rw-r--r--Jellyfin.Api/Constants/Policies.cs5
-rw-r--r--Jellyfin.Api/Controllers/DlnaServerController.cs3
-rw-r--r--Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs9
6 files changed, 76 insertions, 1 deletions
diff --git a/Jellyfin.Api/Auth/AnonymousLanAccessPolicy/AnonymousLanAccessHandler.cs b/Jellyfin.Api/Auth/AnonymousLanAccessPolicy/AnonymousLanAccessHandler.cs
new file mode 100644
index 000000000..88af08dd3
--- /dev/null
+++ b/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;
+ }
+ }
+}
diff --git a/Jellyfin.Api/Auth/AnonymousLanAccessPolicy/AnonymousLanAccessRequirement.cs b/Jellyfin.Api/Auth/AnonymousLanAccessPolicy/AnonymousLanAccessRequirement.cs
new file mode 100644
index 000000000..49af24ff3
--- /dev/null
+++ b/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
+ {
+ }
+}
diff --git a/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs b/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs
index 392498c53..13d3257df 100644
--- a/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs
+++ b/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;
diff --git a/Jellyfin.Api/Constants/Policies.cs b/Jellyfin.Api/Constants/Policies.cs
index 632dedb3c..a72eeea28 100644
--- a/Jellyfin.Api/Constants/Policies.cs
+++ b/Jellyfin.Api/Constants/Policies.cs
@@ -46,6 +46,11 @@ namespace Jellyfin.Api.Constants
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>
public const string FirstTimeSetupOrIgnoreParentalControl = "FirstTimeSetupOrIgnoreParentalControl";
diff --git a/Jellyfin.Api/Controllers/DlnaServerController.cs b/Jellyfin.Api/Controllers/DlnaServerController.cs
index 694d16ad9..4e8c01577 100644
--- a/Jellyfin.Api/Controllers/DlnaServerController.cs
+++ b/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;
diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
index 867f79b6b..e853609d6 100644
--- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
+++ b/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());
+ });
});
}