CustomAuthenticationHandler.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using System.Security.Authentication;
  2. using System.Security.Claims;
  3. using System.Text.Encodings.Web;
  4. using System.Threading.Tasks;
  5. using Jellyfin.Api.Constants;
  6. using Jellyfin.Data.Enums;
  7. using MediaBrowser.Controller.Net;
  8. using Microsoft.AspNetCore.Authentication;
  9. using Microsoft.Extensions.Logging;
  10. using Microsoft.Extensions.Options;
  11. namespace Jellyfin.Api.Auth
  12. {
  13. /// <summary>
  14. /// Custom authentication handler wrapping the legacy authentication.
  15. /// </summary>
  16. public class CustomAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
  17. {
  18. private readonly IAuthService _authService;
  19. /// <summary>
  20. /// Initializes a new instance of the <see cref="CustomAuthenticationHandler" /> class.
  21. /// </summary>
  22. /// <param name="authService">The jellyfin authentication service.</param>
  23. /// <param name="options">Options monitor.</param>
  24. /// <param name="logger">The logger.</param>
  25. /// <param name="encoder">The url encoder.</param>
  26. /// <param name="clock">The system clock.</param>
  27. public CustomAuthenticationHandler(
  28. IAuthService authService,
  29. IOptionsMonitor<AuthenticationSchemeOptions> options,
  30. ILoggerFactory logger,
  31. UrlEncoder encoder,
  32. ISystemClock clock) : base(options, logger, encoder, clock)
  33. {
  34. _authService = authService;
  35. }
  36. /// <inheritdoc />
  37. protected override Task<AuthenticateResult> HandleAuthenticateAsync()
  38. {
  39. var authenticatedAttribute = new AuthenticatedAttribute
  40. {
  41. IgnoreLegacyAuth = true
  42. };
  43. try
  44. {
  45. var user = _authService.Authenticate(Request, authenticatedAttribute);
  46. if (user == null)
  47. {
  48. return Task.FromResult(AuthenticateResult.NoResult());
  49. // TODO return when legacy API is removed.
  50. // Don't spam the log with "Invalid User"
  51. // return Task.FromResult(AuthenticateResult.Fail("Invalid user"));
  52. }
  53. var claims = new[]
  54. {
  55. new Claim(ClaimTypes.Name, user.Username),
  56. new Claim(
  57. ClaimTypes.Role,
  58. value: user.HasPermission(PermissionKind.IsAdministrator) ? UserRoles.Administrator : UserRoles.User)
  59. };
  60. var identity = new ClaimsIdentity(claims, Scheme.Name);
  61. var principal = new ClaimsPrincipal(identity);
  62. var ticket = new AuthenticationTicket(principal, Scheme.Name);
  63. return Task.FromResult(AuthenticateResult.Success(ticket));
  64. }
  65. catch (AuthenticationException ex)
  66. {
  67. return Task.FromResult(AuthenticateResult.Fail(ex));
  68. }
  69. catch (SecurityException ex)
  70. {
  71. return Task.FromResult(AuthenticateResult.Fail(ex));
  72. }
  73. }
  74. }
  75. }