9p4 / jellyfin-plugin-sso

This plugin allows users to sign in through an SSO provider (such as Google, Microsoft, or your own provider). This enables one-click signin.
GNU General Public License v3.0
590 stars 27 forks source link

Stuck at "Logging in..." using Authentik with web client, was working correctly previously. #204

Closed OmniBlade closed 1 month ago

OmniBlade commented 1 month ago

Describe the bug When the SSO login is used through the web app it hangs on "Logging in...". Similar to #189 Jellyfin version 10.9.8 OIDC = Authentik.

To Reproduce Steps to reproduce the behavior:

  1. Open browser and go to jellyfin URL
  2. Click on button to redirect to authentik
  3. Log in.
  4. get stuck at "Logging in..." message

Expected behavior Log in correctly

Configuration

<?xml version="1.0" encoding="utf-8"?>
<PluginConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmln>
  <SamlConfigs />
  <OidConfigs>
    <item>
      <key>
        <string>Authentik</string>
      </key>
      <value>
        <PluginConfiguration>
          <OidEndpoint>https://authentik.domain.name/application/o/jellyfin</OidEndpoint>
          <OidClientId>HASH</OidClientId>
          <OidSecret>HASH</OidSecret>
          <Enabled>true</Enabled>
          <EnableAuthorization>true</EnableAuthorization>
          <EnableAllFolders>false</EnableAllFolders>
          <EnabledFolders />
          <AdminRoles>
            <string>jellyfin Admins</string>
          </AdminRoles>
          <Roles>
            <string>family Users</string>
          </Roles>
          <EnableFolderRoles>true</EnableFolderRoles>
          <EnableLiveTvRoles>false</EnableLiveTvRoles>
          <EnableLiveTv>false</EnableLiveTv>
          <EnableLiveTvManagement>false</EnableLiveTvManagement>
          <LiveTvRoles />
          <LiveTvManagementRoles />
          <FolderRoleMappings>
            <FolderRoleMappings>
              <Role>family Users</Role>
              <Folders>
                <string>HASH</string>
                <string>HASH</string>
                <string>HASH</string>
              </Folders>
            </FolderRoleMappings>
            <FolderRoleMappings>
           <RoleClaim>groups</RoleClaim>
          <OidScopes />
          <NewPath>false</NewPath>
          <CanonicalLinks>
            <item>
              <key>
                <string>user</string>
              </key>
              <value>
                <guid>GUID</guid>
              </value>
            </item>
          </CanonicalLinks>
          <DefaultUsernameClaim>email</DefaultUsernameClaim>
          <DisableHttps>false</DisableHttps>
          <DoNotValidateEndpoints>false</DoNotValidateEndpoints>
          <DoNotValidateIssuerName>false</DoNotValidateIssuerName>
        </PluginConfiguration>
      </value>
    </item>
  </OidConfigs>
</PluginConfiguration>

Versions (please complete the following information):

Additional context I previously had this working, but it seems to have broken either by some inadvertent config change or due to a recent authentik update. Using web developer tools it appears there is a XHR failure on https://jellyfin.domain.name/sso/OID/Auth/Authentik.

mpedziwiatr02 commented 1 month ago

I see the same for Jellyfin version 10.9.9, Plugin version 3.5.2.4.

Logs


[2024-08-17 13:33:46.659 +00:00] [INF] [86] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[2024-08-17 13:33:46.660 +00:00] [ERR] [86] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request. URL "POST" "/sso/OID/Auth/authentik".
System.NullReferenceException: Object reference not set to an instance of an object.
   at Jellyfin.Plugin.SSO_Auth.Api.SSOController.Authenticate(Guid userId, Boolean isAdmin, Boolean enableAuthorization, Boolean enableAllFolders, String[] enabledFolders, Boolean enableLiveTv, Boolean enableLiveTvAdmin, AuthResponse authResponse, String defaultProvider)
   at Jellyfin.Plugin.SSO_Auth.Api.SSOController.OidAuth(String provider, AuthResponse response)
   at lambda_method1738(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Jellyfin.Api.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
   at Jellyfin.Api.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)
   at Jellyfin.Api.Middleware.IPBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager)
   at Jellyfin.Api.Middleware.LanFilteringMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Api.Middleware.QueryStringDecodingMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.ReDoc.ReDocMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Api.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext)
   at Jellyfin.Api.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context)
   at Jellyfin.Api.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager)
   at Jellyfin.Api.Middleware.ExceptionMiddleware.Invoke(HttpContext context)
9p4 commented 1 month ago

@OmniBlade Can you please upload the Jellyfin logs?

OmniBlade commented 1 month ago

This is the log from my instance for an SSO attempt:

[2024-08-19 10:00:13.586 +01:00] [INF] [4] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[2024-08-19 10:00:14.019 +01:00] [INF] [4] Emby.Server.Implementations.ScheduledTasks.TaskManager: "Webhook Item Added Notifier" Completed after 0 minute(s) and 0 seconds
[2024-08-19 10:00:17.355 +01:00] [INF] [4] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[2024-08-19 10:00:22.891 +01:00] [INF] [35] Jellyfin.Plugin.SSO_Auth.Api.SSOController: Is request linking: False
[2024-08-19 10:00:24.349 +01:00] [INF] [27] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[2024-08-19 10:00:24.352 +01:00] [ERR] [27] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request. URL "POST" "/sso/OID/Auth/Authentik".
System.ArgumentException: Invalid username (Parameter 'name')
   at Jellyfin.Server.Implementations.Users.UserManager.GetUserByName(String name)
   at Jellyfin.Plugin.SSO_Auth.Api.SSOController.CreateCanonicalLinkAndUserIfNotExist(String mode, String provider, String canonicalName)
   at Jellyfin.Plugin.SSO_Auth.Api.SSOController.OidAuth(String provider, AuthResponse response)
   at lambda_method314(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Jellyfin.Api.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
   at Jellyfin.Api.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)
   at Jellyfin.Api.Middleware.IPBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager)
   at Jellyfin.Api.Middleware.LanFilteringMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Api.Middleware.QueryStringDecodingMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.ReDoc.ReDocMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Api.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext)
   at Jellyfin.Api.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context)
   at Jellyfin.Api.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager)
   at Jellyfin.Api.Middleware.ExceptionMiddleware.Invoke(HttpContext context)
9p4 commented 1 month ago

You two have different issues. @OmniBlade your issue is caused by Jellyfin's username sanitization. Because you are using the email field, which has an @ in it, it fails the Jellyfin username verification. You'll have to switch to using preferred_username or sub or something instead.

I have been thinking about how to best "normalize" the usernames to prevent this kind of issue (https://github.com/9p4/jellyfin-plugin-sso/issues/199). There are two approaches to this: first is to strip out all special characters, but that would cause collisions (ie two different SSO users, one named user1@ and another named user1 would both share Jellyfin account user1 if the extraneous characters are stripped). Another option is to add an option to "hash" usernames, which would be much more secure and normalize into hexadecimal. A third option would be to create a complicated escaping system on the usernames to normalize them, but that would be difficult and likely open security vulnerabilities.

What do you think I should do?

9p4 commented 1 month ago

I'm going to mark this as a duplicate of https://github.com/9p4/jellyfin-plugin-sso/issues/199, we can continue the conversation there.

9p4 commented 1 month ago

@mpedziwiatr02 can you open a new issue/discussion post, as your issue is likely not related.

mpedziwiatr02 commented 1 month ago

@9p4 nevermind, I fixed it by removing the affected item in CanonicalLinks and restarting Jellyfin (it was working for other accounts and not for mine). Now it seems fine, I'll open an issue if I encounter any more problems.