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
628 stars 29 forks source link

System.ArgumentNullException: Value cannot be null. (Parameter 'collection') #140

Open elysweyr opened 1 year ago

elysweyr commented 1 year ago

Describe the bug This bug affects the plugin's OIDC callback URL which prevents users from being authenticated. This bug isn't related to #130

To Reproduce Steps to reproduce the behavior:

  1. Configure SSO plugin (OIDC)
  2. Configure OIDC client (Keycloak in my case)
  3. Go to https://jellyfin.mydomain/sso/OID/start/elys-sso
  4. Log in with user
  5. See error
[12:51:40] [INF] [95] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[12:51:41] [INF] [100] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[12:51:41] [ERR] [95] Jellyfin.Server.Middleware.ExceptionMiddleware: Error processing request. URL GET /sso/OID/redirect/elys-sso.
System.ArgumentNullException: Value cannot be null. (Parameter 'collection')
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at Jellyfin.Plugin.SSO_Auth.Api.SSOController.OidPost(String provider, String state)
   at lambda_method1041(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(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>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   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>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   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 Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Jellyfin.Server.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
   at Jellyfin.Server.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)
   at Jellyfin.Server.Middleware.IpBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager)
   at Jellyfin.Server.Middleware.LanFilteringMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Server.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.Server.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext)
   at Jellyfin.Server.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context)
   at Jellyfin.Server.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager)
   at Jellyfin.Server.Middleware.ExceptionMiddleware.Invoke(HttpContext context)

Expected behavior Successful standard OIDC flow

Configuration Configuration URL (POST against): https://jellyfin.mydomain/sso/OID/Add/elys-sso?api_key=<api-key> Request payload (JSON):

{
    "oidEndpoint": "https://sso.mydomain/realms/elysweyr",
    "oidClientId": "jellyfin",
    "oidSecret": <secret>,
    "enabled": true,
    "enableAuthorization": true,
    "enableAllFolders": true,
    "roles": ["jellfin-user"],
    "adminRoles": ["jellyfin-admin"],
    "roleClaim": "realm_access.roles",
    "oidScopes": ["openid"]
}

SSO-Auth.xml

<?xml version="1.0" encoding="utf-8"?>
<PluginConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <SamlConfigs />
  <OidConfigs>
    <item>
      <key>
        <string>elys-sso</string>
      </key>
      <value>
        <PluginConfiguration>
          <OidEndpoint>https://sso.mydomain/realms/elysweyr</OidEndpoint>
          <OidClientId>jellyfin</OidClientId>
          <OidSecret>SECRET</OidSecret>
          <Enabled>true</Enabled>
          <EnableAuthorization>true</EnableAuthorization>
          <EnableAllFolders>true</EnableAllFolders>
          <AdminRoles>
            <string>jellyfin-admin</string>
          </AdminRoles>
          <Roles>
            <string>jellfin-user</string>
          </Roles>
          <EnableFolderRoles>false</EnableFolderRoles>
          <EnableLiveTvRoles>false</EnableLiveTvRoles>
          <EnableLiveTv>false</EnableLiveTv>
          <EnableLiveTvManagement>false</EnableLiveTvManagement>
          <RoleClaim>realm_access.roles</RoleClaim>
          <OidScopes>
            <string>openid</string>
          </OidScopes>
          <CanonicalLinks />
          <DisableHttps>false</DisableHttps>
          <DoNotValidateEndpoints>false</DoNotValidateEndpoints>
          <DoNotValidateIssuerName>false</DoNotValidateIssuerName>
        </PluginConfiguration>
      </value>
    </item>
  </OidConfigs>
</PluginConfiguration>

Versions (please complete the following information):

9p4 commented 1 year ago

could you add <EnabledFolders /> to the XML configuration and restart Jellyfin?

9p4 commented 1 year ago

Is this still an issue?