aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBaronGreenback <jimcartlidge@yahoo.co.uk>2021-04-10 12:03:52 +0100
committerBaronGreenback <jimcartlidge@yahoo.co.uk>2021-04-10 12:03:52 +0100
commit5fb7557763566ef4345aa563c4c1b6d81ce3ff57 (patch)
tree7507b20629eae57d9743a47bda8a1eb96b35eb5e
parent221d9373e857d008ac9c1426e856ae3da1200701 (diff)
Network Access Policy
-rw-r--r--Jellyfin.Api/Auth/BaseAuthorizationHandler.cs12
-rw-r--r--Jellyfin.Api/Auth/NetworkAccessPolicy/NetworkAccessHandler.cs48
-rw-r--r--Jellyfin.Api/Auth/NetworkAccessPolicy/NetworkAccessRequirement.cs11
-rw-r--r--Jellyfin.Api/Constants/Policies.cs5
-rw-r--r--Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs11
5 files changed, 85 insertions, 2 deletions
diff --git a/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs b/Jellyfin.Api/Auth/BaseAuthorizationHandler.cs
index 7d68aecf9..456f45d97 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;
@@ -37,6 +37,16 @@ namespace Jellyfin.Api.Auth
}
/// <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>
/// <param name="claimsPrincipal">Request claims.</param>
diff --git a/Jellyfin.Api/Auth/NetworkAccessPolicy/NetworkAccessHandler.cs b/Jellyfin.Api/Auth/NetworkAccessPolicy/NetworkAccessHandler.cs
new file mode 100644
index 000000000..e6b33f565
--- /dev/null
+++ b/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;
+ }
+ }
+}
diff --git a/Jellyfin.Api/Auth/NetworkAccessPolicy/NetworkAccessRequirement.cs b/Jellyfin.Api/Auth/NetworkAccessPolicy/NetworkAccessRequirement.cs
new file mode 100644
index 000000000..b5431501b
--- /dev/null
+++ b/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
+ {
+ }
+}
diff --git a/Jellyfin.Api/Constants/Policies.cs b/Jellyfin.Api/Constants/Policies.cs
index 632dedb3c..d98debd0a 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 local LAN access.
+ /// </summary>
+ public const string NetworkAccessPolicy = "NetworkAccessPolicy";
+
+ /// <summary>
/// Policy name for escaping schedule controls or requiring first time setup.
/// </summary>
public const string FirstTimeSetupOrIgnoreParentalControl = "FirstTimeSetupOrIgnoreParentalControl";
diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
index 2b34370a0..48afc2b8c 100644
--- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
+++ b/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());
+ });
});
}