aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Auth
diff options
context:
space:
mode:
authorCody Robibero <cody@robibe.ro>2021-10-26 17:43:36 -0600
committerCody Robibero <cody@robibe.ro>2021-10-26 17:43:36 -0600
commitf78f1e834ce1907157d4d43cf8564cf40d05fb9f (patch)
treebeb4e348e4d338a8b459f8a421ba19409d478ba9 /Jellyfin.Api/Auth
parent2888567ea53c1c839b0cd69e0ec1168cf51f36a8 (diff)
parent39d5bdac96b17eb92bd304736cc2728832e1cad0 (diff)
Merge remote-tracking branch 'upstream/master' into client-logger
Diffstat (limited to 'Jellyfin.Api/Auth')
-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.cs7
-rw-r--r--Jellyfin.Api/Auth/CustomAuthenticationHandler.cs10
-rw-r--r--Jellyfin.Api/Auth/FirstTimeSetupOrDefaultPolicy/FirstTimeSetupOrDefaultHandler.cs6
-rw-r--r--Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs6
-rw-r--r--Jellyfin.Api/Auth/SyncPlayAccessPolicy/SyncPlayAccessHandler.cs4
7 files changed, 75 insertions, 16 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 7d68aecf9..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;
@@ -77,8 +77,9 @@ namespace Jellyfin.Api.Auth
return false;
}
- var ip = _httpContextAccessor.HttpContext.GetNormalizedRemoteIp();
- var isInLocalNetwork = _networkManager.IsInLocalNetwork(ip);
+ var isInLocalNetwork = _httpContextAccessor.HttpContext != null
+ && _networkManager.IsInLocalNetwork(_httpContextAccessor.HttpContext.GetNormalizedRemoteIp());
+
// User cannot access remotely and user is remote
if (!user.HasPermission(PermissionKind.EnableRemoteAccess) && !isInLocalNetwork)
{
diff --git a/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs
index c56233794..369e846ae 100644
--- a/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs
+++ b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs
@@ -40,11 +40,11 @@ namespace Jellyfin.Api.Auth
}
/// <inheritdoc />
- protected override Task<AuthenticateResult> HandleAuthenticateAsync()
+ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
try
{
- var authorizationInfo = _authService.Authenticate(Request);
+ var authorizationInfo = await _authService.Authenticate(Request).ConfigureAwait(false);
var role = UserRoles.User;
if (authorizationInfo.IsApiKey || authorizationInfo.User.HasPermission(PermissionKind.IsAdministrator))
{
@@ -68,16 +68,16 @@ namespace Jellyfin.Api.Auth
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, Scheme.Name);
- return Task.FromResult(AuthenticateResult.Success(ticket));
+ return AuthenticateResult.Success(ticket);
}
catch (AuthenticationException ex)
{
_logger.LogDebug(ex, "Error authenticating with {Handler}", nameof(CustomAuthenticationHandler));
- return Task.FromResult(AuthenticateResult.NoResult());
+ return AuthenticateResult.NoResult();
}
catch (SecurityException ex)
{
- return Task.FromResult(AuthenticateResult.Fail(ex));
+ return AuthenticateResult.Fail(ex);
}
}
}
diff --git a/Jellyfin.Api/Auth/FirstTimeSetupOrDefaultPolicy/FirstTimeSetupOrDefaultHandler.cs b/Jellyfin.Api/Auth/FirstTimeSetupOrDefaultPolicy/FirstTimeSetupOrDefaultHandler.cs
index 9815e252e..dd0bd4ec2 100644
--- a/Jellyfin.Api/Auth/FirstTimeSetupOrDefaultPolicy/FirstTimeSetupOrDefaultHandler.cs
+++ b/Jellyfin.Api/Auth/FirstTimeSetupOrDefaultPolicy/FirstTimeSetupOrDefaultHandler.cs
@@ -32,18 +32,18 @@ namespace Jellyfin.Api.Auth.FirstTimeSetupOrDefaultPolicy
}
/// <inheritdoc />
- protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, FirstTimeSetupOrDefaultRequirement firstTimeSetupOrDefaultRequirement)
+ protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, FirstTimeSetupOrDefaultRequirement requirement)
{
if (!_configurationManager.CommonConfiguration.IsStartupWizardCompleted)
{
- context.Succeed(firstTimeSetupOrDefaultRequirement);
+ context.Succeed(requirement);
return Task.CompletedTask;
}
var validated = ValidateClaims(context.User);
if (validated)
{
- context.Succeed(firstTimeSetupOrDefaultRequirement);
+ context.Succeed(requirement);
}
else
{
diff --git a/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs b/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs
index decbe0c03..90b76ee99 100644
--- a/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs
+++ b/Jellyfin.Api/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandler.cs
@@ -33,18 +33,18 @@ namespace Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy
}
/// <inheritdoc />
- protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, FirstTimeSetupOrElevatedRequirement firstTimeSetupOrElevatedRequirement)
+ protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, FirstTimeSetupOrElevatedRequirement requirement)
{
if (!_configurationManager.CommonConfiguration.IsStartupWizardCompleted)
{
- context.Succeed(firstTimeSetupOrElevatedRequirement);
+ context.Succeed(requirement);
return Task.CompletedTask;
}
var validated = ValidateClaims(context.User);
if (validated && context.User.IsInRole(UserRoles.Administrator))
{
- context.Succeed(firstTimeSetupOrElevatedRequirement);
+ context.Succeed(requirement);
}
else
{
diff --git a/Jellyfin.Api/Auth/SyncPlayAccessPolicy/SyncPlayAccessHandler.cs b/Jellyfin.Api/Auth/SyncPlayAccessPolicy/SyncPlayAccessHandler.cs
index b898ac76c..e6c04eb08 100644
--- a/Jellyfin.Api/Auth/SyncPlayAccessPolicy/SyncPlayAccessHandler.cs
+++ b/Jellyfin.Api/Auth/SyncPlayAccessPolicy/SyncPlayAccessHandler.cs
@@ -51,7 +51,7 @@ namespace Jellyfin.Api.Auth.SyncPlayAccessPolicy
{
if (user.SyncPlayAccess == SyncPlayUserAccessType.CreateAndJoinGroups
|| user.SyncPlayAccess == SyncPlayUserAccessType.JoinGroups
- || _syncPlayManager.IsUserActive(userId!.Value))
+ || _syncPlayManager.IsUserActive(userId.Value))
{
context.Succeed(requirement);
}
@@ -85,7 +85,7 @@ namespace Jellyfin.Api.Auth.SyncPlayAccessPolicy
}
else if (requirement.RequiredAccess == SyncPlayAccessRequirementType.IsInGroup)
{
- if (_syncPlayManager.IsUserActive(userId!.Value))
+ if (_syncPlayManager.IsUserActive(userId.Value))
{
context.Succeed(requirement);
}