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
578 stars 27 forks source link

Connexion impossible via authelia #134

Closed duncan-valleix closed 1 year ago

duncan-valleix commented 1 year ago
  1. Describe the bug

I can't set up the connection via authelia despite trying several times, I always get an error either in authelia when I callhttps://jellyfin.ndd.com/sso/OID/p/authelia or https://jellyfin.ndd.com/sso/OID/start/authelia, I have this error{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. The 'redirect_uri' parameter does not match any of the OAuth 2.0 Client's pre-registered redirect urls."} be at jellyfin's level when I call https://jellyfin.ndd.com/sso/OID/r/authelia or https://jellyfin.ndd.com/sso/OID/redirect/authelia, I have this error Error processing request.

Versions:

  1. Here are my config files

authelia

      - id: jellyfin
        description: My media server
        # Client secret should be randomly generated
        secret: REDACTED
        authorization_policy: one_factor
        redirect_uris:
          - https://jellyfin.ndd.com/sso/OID/redirect/authelia

jellyfin

<?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>authelia</string>
      </key>
      <value>
        <PluginConfiguration>
          <OidEndpoint>https://auth.ndd.com</OidEndpoint> 
          <OidClientId>jellyfin</OidClientId>
          <OidSecret>REDACTED</OidSecret>
          <Enabled>true</Enabled>
          <EnableAuthorization>true</EnableAuthorization>
          <EnableAllFolders>true</EnableAllFolders>
          <EnabledFolders />
          <AdminRoles />
          <Roles />
          <EnableFolderRoles>false</EnableFolderRoles>
          <EnableLiveTvRoles>false</EnableLiveTvRoles>
          <EnableLiveTv>false</EnableLiveTv>
          <EnableLiveTvManagement>false</EnableLiveTvManagement>
          <LiveTvRoles />
          <LiveTvManagementRoles />
          <FolderRoleMappings />
          <RoleClaim>groups</RoleClaim>
          <OidScopes>groups</OidScopes>
          <DefaultProvider>Jellyfin.Server.Implementations.Users.DefaultAuthenticationProvider</DefaultProvider>
          <CanonicalLinks />
          <DisableHttps>false</DisableHttps>
          <DoNotValidateEndpoints>false</DoNotValidateEndpoints>
          <DoNotValidateIssuerName>false</DoNotValidateIssuerName>
        </PluginConfiguration>
      </value>
    </item>
  </OidConfigs>
</PluginConfiguration>

in the authelia config file I tried putting (one by one) after modification I also restarted authelia

        redirect_uris:
          - https://jellyfin.ndd.com/sso/OID/r/authelia
          - https://jellyfin.ndd.com/sso/OID/p/authelia
          - https://jellyfin.ndd.com/sso/OID/start/authelia
          - https://jellyfin.ndd.com/sso/OID/redirect/authelia
        redirect_uri:
          - https://jellyfin.ndd.com/sso/OID/r/authelia
          - https://jellyfin.ndd.com/sso/OID/p/authelia
          - https://jellyfin.ndd.com/sso/OID/start/authelia
          - https://jellyfin.ndd.com/sso/OID/redirect/authelia

when I put redirect_uri authelia won't start, I even tried to set the scopes

        scopes :
          - openid
          - email
          - profile
          - groups

in the jellyfin config I tested various configurations (one by one))

          <OidEndpoint>https://auth.ndd.com</OidEndpoint> 
          <OidEndpoint>https://auth.ndd.com/.well-known/openid-configuration</OidEndpoint> 
          <OidScopes>["groups"]</OidScopes>

I even tried with and without admin roles and roles.

  1. Les logs

As for logs, here's what happens when I get the error with authelia the authelia log

time="2023-08-20T10:29:58+02:00" level=error msg="Authorization Request failed with error: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. The 'redirect_uri' parameter does not match any of the OAuth 2.0 Client's pre-registered redirect urls." method=GET path=/api/oidc/authorization remote_ip=10.0.20.50 stack="github.com/authelia/authelia/v4/internal/handlers/handler_oidc_authorization.go:32
OpenIDConnectAuthorization\ngithub.com/authelia/authelia/v4/internal/middlewares/http_to_authelia_handler_adaptor.go:113
NewHTTPToAutheliaHandlerAdaptor.func1\ngithub.com/authelia/authelia/v4/internal/middlewares/bridge.go:54
(*BridgeBuilder).Build.func1.1\ngithub.com/authelia/authelia/v4/internal/middlewares/headers.go:35
SecurityHeadersNoStore.func1\ngithub.com/authelia/authelia/v4/internal/middlewares/headers.go:25
SecurityHeadersCSPNone.func1\ngithub.com/authelia/authelia/v4/internal/middlewares/headers.go:16
SecurityHeaders.func1\ngithub.com/authelia/authelia/v4/internal/middlewares/cors.go:216
(*CORSPolicy).Middleware.func1\ngithub.com/fasthttp/router@v1.4.14/router.go:414
(*Router).Handler\ngithub.com/valyala/fasthttp@v1.43.0/http.go:154
(*Response).StatusCode\ngithub.com/valyala/fasthttp@v1.43.0/server.go:2338
(*Server).serveConn\ngithub.com/valyala/fasthttp@v1.43.0/workerpool.go:224
(*workerPool).workerFunc\ngithub.com/valyala/fasthttp@v1.43.0/workerpool.go:196
(*workerPool).getCh.func1\nruntime/asm_amd64.s:1594
goexit"

jellyfin's log

[11:27:33] [INF] [36] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[11:27:40] [INF] [36] Emby.Server.Implementations.Session.SessionWebSocketListener: Sending ForceKeepAlive message to 1 inactive WebSockets.

and here are the logs when the problem is blocked on jellyfin (I don't reach authelia so I have no logs) jellyfin log for https://jellyfin.ndd.com/sso/OID/r/authelia

[11:34:59] [INF] [74] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[11:34:59] [ERR] [74] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request. URL GET /sso/OID/r/authelia.
System.ArgumentNullException: Value cannot be null. (Parameter 'key')
   at System.Collections.Generic.Dictionary`2.FindValue(TKey key)
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Jellyfin.Plugin.SSO_Auth.Api.SSOController.OidPost(String provider, String state)
   at lambda_method1013(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 Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   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)
[11:36:40] [INF] [24] Emby.Server.Implementations.Session.SessionWebSocketListener: Sending ForceKeepAlive message to 1 inactive WebSockets.

jellyfin log for https://jellyfin.ndd.com/sso/OID/r/authelia

[11:38:06] [INF] [24] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[11:38:06] [ERR] [24] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request. URL GET /sso/OID/redirect/authelia.
System.ArgumentNullException: Value cannot be null. (Parameter 'key')
   at System.Collections.Generic.Dictionary`2.FindValue(TKey key)
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Jellyfin.Plugin.SSO_Auth.Api.SSOController.OidPost(String provider, String state)
   at lambda_method1159(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 Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   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)
[11:39:04] [INF] [48] Emby.Server.Implementations.Session.SessionWebSocketListener: Sending ForceKeepAlive message to 1 inactive WebSockets.
9p4 commented 1 year ago

If you are using the old /p/ paths, then the plugin will use the /r/ paths for the redirect. Instead, try going to /start/ instead of /p/.

9p4 commented 1 year ago

futhermore, OIDScopes should be just a space separated list, not JSON-formatted.

duncan-valleix commented 1 year ago

If you are using the old /p/ paths, then the plugin will use the /r/ paths for the redirect. Instead, try going to /start/ instead of /p/

as mentioned above, I've tried all 4 and the result is the same in the end.

futhermore, OIDScopes should be just a space separated list, not JSON-formatted.

I will take note of this and modify it. thank you.

duncan-valleix commented 1 year ago

in authelia it is currently declared as follows,

      - id: jellyfin
        description: Jellyfin
        # Client secret should be randomly generated
        secret: '$pbkdf2-sha512$REDACTED'
        authorization_policy: one_factor
        redirect_uris:
          - https://jellyfin.ndd.com/sso/OID/redirect/authelia

in jellyfin like this

<OidEndpoint>https://auth.ndd.com</OidEndpoint>

so if I call https://jellyfin.ndd.com/sso/OID/start/authelia I should have received a favourable reply, but instead I got this one {"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. The 'redirect_uri' parameter does not match any of the OAuth 2.0 Client's pre-registered redirect urls."}

9p4 commented 1 year ago

Can you upload the whole Jellyfin log? I need to see what happens when you go to /start/authelia

duncan-valleix commented 1 year ago

Can you upload the whole Jellyfin log? I need to see what happens when you go to /start/authelia

when I make a call from /start/authelia I have this in the jellyfin log

[18:11:58] [INF] [23] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized

and I have this in authelia's log

time="2023-08-20T18:14:34+02:00" level=debug msg="Notifier SMTP client attempting connection to smtp.gmail.com:465"
time="2023-08-20T18:14:34+02:00" level=debug msg="Notifier SMTP client using submissions port 465. Make sure the mail server you are connecting to is configured for submissions and not SMTPS."
time="2023-08-20T18:14:34+02:00" level=debug msg="Notifier SMTP client connected successfully"
time="2023-08-20T18:14:34+02:00" level=debug msg="Notifier SMTP connection is already encrypted, skipping STARTTLS"
time="2023-08-20T18:14:34+02:00" level=debug msg="Notifier SMTP server supports authentication with the following mechanisms: LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH"
time="2023-08-20T18:14:34+02:00" level=debug msg="Notifier SMTP client attempting AUTH PLAIN with server"
time="2023-08-20T18:14:34+02:00" level=debug msg="Notifier SMTP client authenticated successfully with the server"
time="2023-08-20T18:14:34+02:00" level=info msg="Initializing server for non-TLS connections on '[::]:9091' path '/'"
time="2023-08-20T18:14:51+02:00" level=error msg="Authorization Request failed with error: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. The 'redirect_uri' parameter does not match any of the OAuth 2.0 Client's pre-registered redirect urls." method=GET path=/api/oidc/authorization remote_ip=10.0.20.50 stack="github.com/authelia/authelia/v4/internal/handlers/handler_oidc_authorization.go:32           OpenIDConnectAuthorization\ngithub.com/authelia/authelia/v4/internal/middlewares/http_to_authelia_handler_adaptor.go:113 NewHTTPToAutheliaHandlerAdaptor.func1\ngithub.com/authelia/authelia/v4/internal/middlewares/bridge.go:54                            (*BridgeBuilder).Build.func1.1\ngithub.com/authelia/authelia/v4/internal/middlewares/headers.go:35                           SecurityHeadersNoStore.func1\ngithub.com/authelia/authelia/v4/internal/middlewares/headers.go:25                           SecurityHeadersCSPNone.func1\ngithub.com/authelia/authelia/v4/internal/middlewares/headers.go:16                           SecurityHeaders.func1\ngithub.com/authelia/authelia/v4/internal/middlewares/cors.go:216                             (*CORSPolicy).Middleware.func1\ngithub.com/fasthttp/router@v1.4.14/router.go:414                                             (*Router).Handler\ngithub.com/valyala/fasthttp@v1.43.0/http.go:154                                              (*Response).StatusCode\ngithub.com/valyala/fasthttp@v1.43.0/server.go:2338                                           (*Server).serveConn\ngithub.com/valyala/fasthttp@v1.43.0/workerpool.go:224                                        (*workerPool).workerFunc\ngithub.com/valyala/fasthttp@v1.43.0/workerpool.go:196                                        (*workerPool).getCh.func1\nruntime/asm_amd64.s:1594                                                                     goexit"
9p4 commented 1 year ago

Can you force the redirect scheme to be "https"? This should be the "scheme override" option in the settings.

duncan-valleix commented 1 year ago

Can you force the redirect scheme to be "https"? This should be the "scheme override" option in the settings.

it works, so I guess that was the problem. many thanks

9p4 commented 1 year ago

It seems like your reverse proxy is misconfigured and not sending Jellyfin the right headers that lets it know that it is running over HTTPS. Jellyfin was then using "http" instead of "https" to generate the redirect url, which caused the issue.

See also: https://github.com/9p4/jellyfin-plugin-sso/issues/129 and many more.

duncan-valleix commented 1 year ago

It seems like your reverse proxy is misconfigured and not sending Jellyfin the right headers that lets it know that it is running over HTTPS. Jellyfin was then using "http" instead of "https" to generate the redirect url, which caused the issue.

See also: #129 and many more.

this is very likely because between my reverse proxy (traefik) and jellyfin, it communicates via the network with the container_name.http://jellyfin:8096

well now I have a permission problem, do I have to look elsewhere or can you help me?

in the jellyfin log I have this

[18:35:38] [INF] [22] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[18:35:41] [INF] [22] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[18:35:42] [WRN] [20] Jellyfin.Plugin.SSO_Auth.Api.SSOController: OpenID user f6141dcb-3d4e has one or more incorrect role claims: [{"Type": "amr", "Value": "pwd"}, {"Type": "azp", "Value": "jellyfin"}, {"Type": "client_id", "Value": "jellyfin"}, {"Type": "jti", "Value": "4a6dadce-2c66-4f1e-b830-a4dd54e3e975"}, {"Type": "name", "Value": "Prenom NOM"}, {"Type": "preferred_username", "Value": "prenom-nom"}, {"Type": "rat", "Value": "1692549338"}, {"Type": "sub", "Value": "f6141dcb-3d4e-"}]. Expected any one of: ["seedbox_users"]
9p4 commented 1 year ago

You can create a discussion post for the permission error. I can tell you that it looks like authelia is not sending over any group/role information. I'm not very good with authelia, so I won't be of much help with that side of things.

duncan-valleix commented 1 year ago

You can create a discussion post for the permission error. I can tell you that it looks like authelia is not sending over any group/role information. I'm not very good with authelia, so I won't be of much help with that side of things.

I'll have a look at this, thank you very much. :D