diff options
| author | Cody Robibero <cody@robibe.ro> | 2021-12-24 02:41:50 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-24 02:41:50 +0000 |
| commit | 634ce40c2facfbfaf6454ad8d3a7f2aca4723b46 (patch) | |
| tree | cf2f3c660f4dfbd8ea19614a10fc1cc0052d55de /Jellyfin.Api/Auth | |
| parent | 6648b7d7dabeaa84835fc7a8a7a2a468a00cad5c (diff) | |
| parent | b5459f49d32d0fce3944f816915fb7380fd84681 (diff) | |
Merge branch 'master' into comparisons
Diffstat (limited to 'Jellyfin.Api/Auth')
7 files changed, 77 insertions, 14 deletions
diff --git a/Jellyfin.Api/Auth/AnonymousLanAccessPolicy/AnonymousLanAccessHandler.cs b/Jellyfin.Api/Auth/AnonymousLanAccessPolicy/AnonymousLanAccessHandler.cs new file mode 100644 index 0000000000..88af08dd33 --- /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 0000000000..49af24ff3b --- /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 392498c530..13d3257dff 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/Auth/CustomAuthenticationHandler.cs b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs index c56233794a..bd3e7d9e3e 100644 --- a/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs +++ b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs @@ -40,11 +40,16 @@ 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); + if (!authorizationInfo.HasToken) + { + return AuthenticateResult.NoResult(); + } + var role = UserRoles.User; if (authorizationInfo.IsApiKey || authorizationInfo.User.HasPermission(PermissionKind.IsAdministrator)) { @@ -68,16 +73,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 9815e252ee..dd0bd4ec2f 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 decbe0c035..90b76ee99a 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 b898ac76c8..e6c04eb082 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); } |
