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

Authentik "Provider does not exist" OIDC Failure #153

Closed M-Davies closed 11 months ago

M-Davies commented 11 months ago

Describe the bug My Jellyfin instance cannot seem to find my Authentik OIDC provider after deployment in my local Docker media stack. When accessing my SSO url at https://jellyfin.mydomain.tld/sso/OID/p/authentik, I recieve an error in the browser (Error processing request.) and in the logs, the following more detailed error:

[00:17:08] [INF] [126] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[00:17:08] [ERR] [126] Jellyfin.Server.Middleware.ExceptionMiddleware: Error processing request. URL GET /sso/OID/p/authentik.
System.ArgumentException: Provider does not exist
   at Jellyfin.Plugin.SSO_Auth.Api.SSOController.OidChallenge(String provider, Boolean isLinking)
   at lambda_method1607(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()
--- 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.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)

I have attached some screenshots below showing my Authentik and Jellyfin setup that roughly followed the guide in providers.md as well as one on Reddit. Please can you confirm whether this is a me problem or something deeper in the library that could be at fault.

To Reproduce Steps to reproduce the behavior:

  1. Go to https://jellyfin.mydomain.tld/sso/OID/p/authentik
  2. See error

Expected behavior A prompt to login via Authentik should appear

Screenshots Authentik Scope Mapping Setup 2023-12-03 00_26_27-Property Mappings - Admin - authentik

Authentik Provider Setup 2023-12-03 00_23_02-Providers - Admin - authentik 2023-12-03 00_24_15-Providers - Admin - authentik 2023-12-03 00_56_05-Jellyfin-OIDC - Admin - authentik

Authentik Application Setup 2023-12-03 00_25_35-Applications - Admin - authentik

Jellyfin OIDC Settings 2023-12-03 00_28_24-Window 2023-12-03 00_27_53-Plugins 2023-12-03 00_28_44-Plugins

Configuration Available on request via private communication channels, would like to keep detailed logging information out of the public domain if possible

Versions (please complete the following information):

Additional context

9p4 commented 11 months ago

When you navigate to https://jellyfin.mydomain.tld/sso/OID/p/authentik, the authentik part has to match the name of the provider in the Jellyfin configuration exactly. You have the name set to Authentik OAuth. Either you can change this name or visit https://jellyfin.mydomain.tld/sso/OID/p/Authentik%20OAuth.

M-Davies commented 11 months ago

When you navigate to https://jellyfin.mydomain.tld/sso/OID/p/authentik, the authentik part has to match the name of the provider in the Jellyfin configuration exactly. You have the name set to Authentik OAuth. Either you can change this name or visit https://jellyfin.mydomain.tld/sso/OID/p/Authentik%20OAuth.

Thanks for replying so quickly @9p4 :) I changed my provider to Authentik and updated the redirect URLs and launch URL in authentik. That got me past that error but am now hitting a redirect error after navigating to https://jellyfin.mydomain.tld/sso/OID/p/Authentik: image

My redirect URL in Jellyfin is https://jellyfin.mydomain.tld/sso/OID/redirect/Authentik.

I also tried adding https://jellyfin.mydomain.tld/sso/OID/r/Authentik to my redirect URLs but, no matter the order between the two redirect URLs, I get another Error processing request. clientside and some errors in the logs serverside:

[21:02:30] [INF] [96] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[21:02:31] [ERR] [101] Jellyfin.Server.Middleware.ExceptionMiddleware: Error processing request. URL GET /sso/OID/r/Authentik.
System.InvalidOperationException: Error loading discovery document: Endpoint belongs to different authority: https://auth.mydomain.tld/application/o/authorize/
   at IdentityModel.OidcClient.OidcClient.EnsureProviderInformationAsync(CancellationToken cancellationToken) in /_/src/OidcClient/OidcClient.cs:line 410
   at IdentityModel.OidcClient.OidcClient.EnsureConfigurationAsync(CancellationToken cancellationToken) in /_/src/OidcClient/OidcClient.cs:line 371
   at IdentityModel.OidcClient.OidcClient.ProcessResponseAsync(String data, AuthorizeState state, Parameters backChannelParameters, CancellationToken cancellationToken) in /_/src/OidcClient/OidcClient.cs:line 184
   at Jellyfin.Plugin.SSO_Auth.Api.SSOController.OidPost(String provider, String state)
   at lambda_method970(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)
M-Davies commented 11 months ago

Might be related to https://github.com/9p4/jellyfin-plugin-sso/issues/138

9p4 commented 11 months ago

In your list of redirect URLs, can you add the same URL but instead with "r" instead of "redirect"? This was a sloppy mistake on my part when I tried to clarify and simplify paths and just made it more complicated and confusing for everyone else.

M-Davies commented 11 months ago

In your list of redirect URLs, can you add the same URL but instead with "r" instead of "redirect"? This was a sloppy mistake on my part when I tried to clarify and simplify paths and just made it more complicated and confusing for everyone else.

@9p4 So I'm getting the same error I mentioned above, either with r on it's own or alongside redirect:

I also tried adding https://jellyfin.mydomain.tld/sso/OID/r/Authentik to my redirect URLs but, no matter the order between the two redirect URLs, I get another Error processing request. clientside and some errors in the logs serverside:

[21:02:30] [INF] [96] Jellyfin.Plugin.SSO_Auth.Api.SSOController: SSO Controller initialized
[21:02:31] [ERR] [101] Jellyfin.Server.Middleware.ExceptionMiddleware: Error processing request. URL GET /sso/OID/r/Authentik.
System.InvalidOperationException: Error loading discovery document: Endpoint belongs to different authority: https://auth.mydomain.tld/application/o/authorize/
   at IdentityModel.OidcClient.OidcClient.EnsureProviderInformationAsync(CancellationToken cancellationToken) in /_/src/OidcClient/OidcClient.cs:line 410
   at IdentityModel.OidcClient.OidcClient.EnsureConfigurationAsync(CancellationToken cancellationToken) in /_/src/OidcClient/OidcClient.cs:line 371
   at IdentityModel.OidcClient.OidcClient.ProcessResponseAsync(String data, AuthorizeState state, Parameters backChannelParameters, CancellationToken cancellationToken) in /_/src/OidcClient/OidcClient.cs:line 184
   at Jellyfin.Plugin.SSO_Auth.Api.SSOController.OidPost(String provider, String state)
   at lambda_method970(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)
9p4 commented 11 months ago

Can you upload the contents of the .well-known OpenID configuration URL? I want to check if Authentik is replying with the public-facing domain name or if it is instead replying with internal addresses.

M-Davies commented 11 months ago

Can you upload the contents of the .well-known OpenID configuration URL? I want to check if Authentik is replying with the public-facing domain name or if it is instead replying with internal addresses.

{
  "issuer": "https://auth.mydomain.tld/application/o/jellyfin/",
  "authorization_endpoint": "https://auth.mydomain.tld/application/o/authorize/",
  "token_endpoint": "https://auth.mydomain.tld/application/o/token/",
  "userinfo_endpoint": "https://auth.mydomain.tld/application/o/userinfo/",
  "end_session_endpoint": "https://auth.mydomain.tld/application/o/jellyfin/end-session/",
  "introspection_endpoint": "https://auth.mydomain.tld/application/o/introspect/",
  "revocation_endpoint": "https://auth.mydomain.tld/application/o/revoke/",
  "device_authorization_endpoint": "https://auth.mydomain.tld/application/o/device/",
  "response_types_supported": [
    "code",
    "id_token",
    "id_token token",
    "code token",
    "code id_token",
    "code id_token token"
  ],
  "response_modes_supported": [
    "query",
    "fragment",
    "form_post"
  ],
  "jwks_uri": "https://auth.mydomain.tld/application/o/jellyfin/jwks/",
  "grant_types_supported": [
    "authorization_code",
    "refresh_token",
    "implicit",
    "client_credentials",
    "password",
    "urn:ietf:params:oauth:grant-type:device_code"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "subject_types_supported": [
    "public"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_basic"
  ],
  "acr_values_supported": [
    "goauthentik.io/providers/oauth2/default"
  ],
  "scopes_supported": [
    "groups",
    "openid",
    "email",
    "profile"
  ],
  "request_parameter_supported": false,
  "claims_supported": [
    "sub",
    "iss",
    "aud",
    "exp",
    "iat",
    "auth_time",
    "acr",
    "amr",
    "nonce",
    "email",
    "email_verified",
    "name",
    "given_name",
    "preferred_username",
    "nickname",
    "groups"
  ],
  "claims_parameter_supported": false,
  "code_challenge_methods_supported": [
    "plain",
    "S256"
  ]
}

They appear to all be replying with the public facing domain name (I've obfuscated the actual result but the FQDN was the same on all of them)

9p4 commented 11 months ago

In the Jellyfin plugin configuration, there's a checkbox that says, "Do not validate endpoints (insecure)". Try enabling that. Ideally you shouldn't keep it enabled, but this kind of issue usually points to a hard-to-debug configuration issue with how your server is set up.

M-Davies commented 11 months ago

In the Jellyfin plugin configuration, there's a checkbox that says, "Do not validate endpoints (insecure)". Try enabling that. Ideally you shouldn't keep it enabled, but this kind of issue usually points to a hard-to-debug configuration issue with how your server is set up.

That worked :) Thanks for that. Weird on what it could be, I'm using LetsEncrypt for certs everywhere that should be universally trusted

9p4 commented 11 months ago

Usually this is an issue with how the reverse proxy is configured and how it might not be properly forwarding the relevant headers. Out of curiosity, what reverse proxy are you using and do you mind uploading the configuration here?

M-Davies commented 11 months ago

Usually this is an issue with how the reverse proxy is configured and how it might not be properly forwarding the relevant headers. Out of curiosity, what reverse proxy are you using and do you mind uploading the configuration here?

Nginx 1.18.0. Configuration is below:

log_format stripsecrets '$remote_addr $host - $remote_user [$time_local] '
    '"$secretfilter" $status $body_bytes_sent '
    '$request_length $request_time $upstream_response_time '
    '"$http_referer" "$http_user_agent"';

map $request $secretfilter {
    ~*^(?<prefix1>.*[\?&]api_key=)([^&]*)(?<suffix1>.*)$  "${prefix1}***$suffix1";
    default                                               $request;
}

# Uncomment the commented sections after you have acquired a SSL Certificate
server {
    listen 80;
    listen [::]:80;
    server_name jellyfin.mydomain.tld;

    # Uncomment to redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name jellyfin.mydomain.tld;

    ## The default `client_max_body_size` is 1M, this might not be enough for some posters, etc.
    client_max_body_size 20M;

    # Logfile
    access_log /var/log/nginx/access-jellyfin.log stripsecrets;

    ssl_certificate /etc/letsencrypt/live/mydomain.tld/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.tld/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    add_header Strict-Transport-Security "max-age=31536000" always;
    ssl_trusted_certificate /etc/letsencrypt/live/mydomain.tld/chain.pem;
    ssl_stapling on;
    ssl_stapling_verify on;

    # Security / XSS Mitigation Headers
    add_header X-XSS-Protection "0"; # Do NOT enable. This is obsolete/dangerous

    # COOP/COEP. Disable if you use external plugins/images/assets
    add_header Cross-Origin-Opener-Policy "same-origin" always;
    add_header Cross-Origin-Embedder-Policy "require-corp" always;
    add_header Cross-Origin-Resource-Policy "same-origin" always;

    # Tell browsers to use per-origin process isolation
    add_header Origin-Agent-Cluster "?1" always;

    location = / {
        return 302 http://$host/web/;
        return 302 https://$host/web/;
    }

    location / {
        # Proxy main Jellyfin traffic
        proxy_pass http://127.0.0.1:8096;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $http_host;

        # Disable buffering when the nginx proxy gets very resource heavy upon streaming
        proxy_buffering off;
    }

    # location block for /web - This is purely for aesthetics so /web/#!/ works instead of having to go to /web/index.html/#!/
    location = /web/ {
        # Proxy main Jellyfin traffic
        proxy_pass http://127.0.0.1:8096/web/index.html;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
    }

    location /socket {
        # Proxy Jellyfin Websockets traffic
        proxy_pass http://127.0.0.1:8096;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
    }
}
9p4 commented 11 months ago

I don't see anything wrong there. What about the Nginx config for Authentik?