nginx reverse proxy - basic auth not passed to video url (android chrome webbrowser) #541

Closed
opened 2025-12-21 16:53:07 +01:00 by backuprepo · 5 comments
Owner

Originally created by @dedwardsdale on GitHub (Mar 24, 2019).

Describe the bug
When using the Android Chrome web browser to access an installation that is hosted behind an nginx reverse proxy with basic auth, the video files do not play.
Everything else appears to work - dashboard, settings etc.

To Reproduce

  1. Setup Jellyfin behind nginx with basic auth:
server {
  listen 443 ssl;
  server_name jellyfin.my.tld;

  ssl_certificate /etc/letsencrypt/live/my.tld/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/my.tld/privkey.pem;
  include /etc/letsencrypt/options-ssl-nginx.conf;
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

  satisfy any;
  allow 192.168.1.0/24;
  deny all;
  auth_basic "What's the password?";
  auth_basic_user_file /etc/htpasswd;

  location / {
    proxy_pass http://127.0.0.1:8096/;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $remote_addr;
    proxy_set_header X-Forwarded-Protocol $scheme;
    proxy_redirect off;
    # websocket configuration
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }

}
  1. Navigate to jellyfin in android chrome browser and authenticate
  2. Attempt to play video

Expected behavior
Video should play

Logs

[24/Mar/2019:09:55:20 +0000] "GET /emby/videos/d0acf37e-23de-334f-4425-f7b9d7fecf5e/master.m3u8?DeviceId=TW96aWxsYS81LjAgKExpbnV4OyBBbmRyb2lkIDguMC4wOyBTTS1HOTY1RikgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzcyLjAuMzYyNi4xMjEgTW9iaWxlIFNhZmFyaS81MzcuMzZ8MTU1MzQxOTUzNTczMA11&MediaSourceId=d0acf37e23de334f4425f7b9d7fecf5e&VideoCodec=h264&AudioCodec=mp3,aac,opus&AudioStreamIndex=1&VideoBitrate=272000&AudioBitrate=128000&PlaySessionId=17c6a403b8b640cf9e10ffd9f492a010&api_key=REMOVED&SubtitleMethod=Encode&TranscodingMaxAudioChannels=2&RequireAvc=false&Tag=0c33f7d9fa103ecaeb986940df45c0e2&SegmentContainer=ts&MinSegments=1&BreakOnNonKeyFrames=False&h264-profile=high,main,baseline,constrainedbaseline,high10&h264-level=51&TranscodeReasons=ContainerBitrateExceedsLimit HTTP/1.1" 401 606 "-" "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Mobile Safari/537.36"

Screenshots
N/A

System (please complete the following information):

  • OS: Android
  • Browser: Chrome
  • Jellyfin Version: 10.2.2
  • Reverse proxy: nginx

Additional context
I don't know if this is a problem that Jellyfin can fix - googling around it looks like you specifically have to set the basic auth headers in an Android VideoView and I'm not sure if Chrome actually does this:
https://stackoverflow.com/questions/31555875/using-videoview-with-basic-authenticated-urls?rq=1

Originally created by @dedwardsdale on GitHub (Mar 24, 2019). **Describe the bug** When using the Android Chrome web browser to access an installation that is hosted behind an nginx reverse proxy with basic auth, the video files do not play. Everything else appears to work - dashboard, settings etc. **To Reproduce** 1. Setup Jellyfin behind nginx with basic auth: ``` server { listen 443 ssl; server_name jellyfin.my.tld; ssl_certificate /etc/letsencrypt/live/my.tld/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/my.tld/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; satisfy any; allow 192.168.1.0/24; deny all; auth_basic "What's the password?"; auth_basic_user_file /etc/htpasswd; location / { proxy_pass http://127.0.0.1:8096/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $remote_addr; proxy_set_header X-Forwarded-Protocol $scheme; proxy_redirect off; # websocket configuration proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } ``` 2. Navigate to jellyfin in android chrome browser and authenticate 3. Attempt to play video **Expected behavior** Video should play **Logs** ``` [24/Mar/2019:09:55:20 +0000] "GET /emby/videos/d0acf37e-23de-334f-4425-f7b9d7fecf5e/master.m3u8?DeviceId=TW96aWxsYS81LjAgKExpbnV4OyBBbmRyb2lkIDguMC4wOyBTTS1HOTY1RikgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzcyLjAuMzYyNi4xMjEgTW9iaWxlIFNhZmFyaS81MzcuMzZ8MTU1MzQxOTUzNTczMA11&MediaSourceId=d0acf37e23de334f4425f7b9d7fecf5e&VideoCodec=h264&AudioCodec=mp3,aac,opus&AudioStreamIndex=1&VideoBitrate=272000&AudioBitrate=128000&PlaySessionId=17c6a403b8b640cf9e10ffd9f492a010&api_key=REMOVED&SubtitleMethod=Encode&TranscodingMaxAudioChannels=2&RequireAvc=false&Tag=0c33f7d9fa103ecaeb986940df45c0e2&SegmentContainer=ts&MinSegments=1&BreakOnNonKeyFrames=False&h264-profile=high,main,baseline,constrainedbaseline,high10&h264-level=51&TranscodeReasons=ContainerBitrateExceedsLimit HTTP/1.1" 401 606 "-" "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Mobile Safari/537.36" ``` **Screenshots** N/A **System (please complete the following information):** - OS: Android - Browser: Chrome - Jellyfin Version: 10.2.2 - Reverse proxy: nginx **Additional context** I don't know if this is a problem that Jellyfin can fix - googling around it looks like you specifically have to set the basic auth headers in an Android VideoView and I'm not sure if Chrome actually does this: https://stackoverflow.com/questions/31555875/using-videoview-with-basic-authenticated-urls?rq=1
backuprepo 2025-12-21 16:53:07 +01:00
  • closed this issue
  • added the
    stale
    bug
    labels
Author
Owner

@JustAMan commented on GitHub (Mar 25, 2019):

As a workaround I can suggest removing http auth for specifical URLs that are used for playing the video (the one you quoted).

@JustAMan commented on GitHub (Mar 25, 2019): As a workaround I can suggest removing http auth for specifical URLs that are used for playing the video (the one you quoted).
Author
Owner

@joshuaboniface commented on GitHub (Mar 25, 2019):

I wouldn't even call that a workaround - that would be the proper solution. Putting basic auth in front of a program that includes its own auth is just asking for trouble.

@joshuaboniface commented on GitHub (Mar 25, 2019): I wouldn't even call that a workaround - that would be the proper solution. Putting basic auth in front of a program that includes its own auth is just asking for trouble.
Author
Owner

@dedwardsdale commented on GitHub (Mar 26, 2019):

@JustAMan Why didn't I think of that? I will give that a try tonight and check if it leaves open any potential to get to other sections of jellyfin or if that is used only for the streaming component.

@joshuaboniface I don't think this is asking for trouble, nginx is a tried and battle-tested reverse proxy and using it prevents your publicly exposed installation from appearing in tools such as https://www.shodan.io/

Does anyone know if this is an issue jellyfin can fix; or if I should be raising a bug against Chrome for not passing through the basic auth on the VideoView?

@dedwardsdale commented on GitHub (Mar 26, 2019): @JustAMan Why didn't I think of that? I will give that a try tonight and check if it leaves open any potential to get to other sections of jellyfin or if that is used only for the streaming component. @joshuaboniface I don't think this is asking for trouble, nginx is a tried and battle-tested reverse proxy and using it prevents your publicly exposed installation from appearing in tools such as https://www.shodan.io/ Does anyone know if this is an issue jellyfin can fix; or if I should be raising a bug against Chrome for not passing through the basic auth on the VideoView?
Author
Owner

@drago-96 commented on GitHub (Apr 3, 2019):

I think that it would be really nice to use basic auth as a possible authentication method: if the REMOTE_USER variable is set to user123, then Jellyfin should act as if user123 just entered his password, and start his session/set his cookies.

I know this isn't the right solution to authentication, but maybe it's simpler to implement than LDAP/Kerberos/whatever.

@drago-96 commented on GitHub (Apr 3, 2019): I think that it would be really nice to use basic auth as a possible authentication method: if the REMOTE_USER variable is set to `user123`, then Jellyfin should act as if `user123` just entered his password, and start his session/set his cookies. I know this isn't the right solution to authentication, but maybe it's simpler to implement than LDAP/Kerberos/whatever.
Author
Owner

@stale[bot] commented on GitHub (Jul 29, 2019):

Issues go stale after 60d of inactivity. Mark the issue as fresh by adding a comment or commit. Stale issues close after an additional 7d of inactivity. If this issue is safe to close now please do so. If you have any questions you can reach us on Matrix or Social Media.

@stale[bot] commented on GitHub (Jul 29, 2019): Issues go stale after 60d of inactivity. Mark the issue as fresh by adding a comment or commit. Stale issues close after an additional 7d of inactivity. If this issue is safe to close now please do so. If you have any questions you can reach us on [Matrix or Social Media](https://jellyfin.readthedocs.io/en/latest/getting-help/).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: starred/jellyfin#541
No description provided.