Jump to content

Android TV clients cannot authenticate through reverse proxy (browser and Android phone work)


Recommended Posts

Posted

Hi,

I'm hoping someone can help because I've narrowed this down as much as I can.

Environment

  • Emby Server 4.9.5.0
  • QNAP TS-464 and TS-453D
  • Native QPKG installation (not Docker)
  • Nginx Proxy Manager (latest jc21/nginx-proxy-manager)
  • HTTPS using Let's Encrypt
  • Reverse proxy to Emby on HTTP port 8096

Reverse proxy

NPM configuration is very standard:

  • Forward Scheme: HTTP
  • Forward Host: 192.168.x.x
  • Forward Port: 8096
  • Force SSL: Enabled
  • HTTP/2: Enabled
  • WebSockets: Enabled
  • Cache Assets: Disabled
  • Block Common Exploits: Disabled
  • No custom locations
  • No custom nginx directives

Emby Network settings

  • Secure connection mode: Handled by reverse proxy
  • External domain configured
  • Public HTTPS port: 443
  • Local HTTP port: 8096
  • Local HTTPS port: 8920
  • Remote connections enabled
  • UPnP disabled

The strange part

I have two completely separate Emby servers.

  • Different NAS hardware
  • Different databases
  • Same Emby version
  • Same reverse proxy

Both behave identically.

Testing results

Works

  • Windows browser via reverse proxy
  • Android phone browser via reverse proxy
  • Android phone Emby app via reverse proxy
  • Android TV browser (Edge) via reverse proxy
  • Android TV app via local IP
  • OttoAibox Emby app via local IP

Fails

  • Sony Android TV Emby app via reverse proxy
  • OttoAibox Emby app via reverse proxy

Both Android TV devices authenticate correctly if I connect directly to:

http://192.168.x.x:8096
They fail only when using:
https://emby.backup.monitoringcomputers.com.au
 

Emby Connect

Emby Connect also fails.

The PIN page says:

Pin Confirmed. Thank you.

but the TV never completes the login.

Logs

The server receives the authentication request.

Immediately afterwards the log shows:

GET /emby/Users/authenticatebyname
followed by:
Access token is invalid or expired.
401 Unauthorized
 

Browser authentication succeeds through the same reverse proxy.

Why I think this may be a client issue

Everything else works:

  • Browser
  • Android phone app
  • Direct LAN
  • Same reverse proxy
  • Same certificate

Only Android TV-style clients fail when connecting through the reverse proxy.

Has anyone seen this before?

Is there something different about Android TV authentication compared with the Android phone app?

Any suggestions would be appreciated.

Posted

This has never worked through the reverse proxy on Android TV devices. It is not a regression after an update."

Posted

My 80% confidence guess is that your proxy is converting POST calls to GET OR not properly forwarding the POST data on POST calls.

Posted
Quote
GET /emby/Users/authenticatebyname

Ding ding ding. Yes this should be a post. They Emby app sends a post, so something in your stack is modifying the request. I would start by resolving that.

Posted

Thanks for the clue. I'm not using Cloudflare or any CDN. The path is:
Internet → Grandstream GWN7003 port forwarding → Nginx Proxy Manager → Emby.

NPM is using a standard proxy host with:

  • Forward scheme: HTTP
  • Forward host: 192.168.20.10
  • Forward port: 8096
  • WebSockets: Enabled
  • Force SSL: Enabled
  • HTTP/2: Enabled
  • No custom locations
  • No advanced configuration

Is there a particular request or Nginx directive you'd like me to inspect to determine where the POST is being converted to a GET?

Posted
1 hour ago, Breezey said:

Thanks for the clue. I'm not using Cloudflare or any CDN. The path is:
Internet → Grandstream GWN7003 port forwarding → Nginx Proxy Manager → Emby.

NPM is using a standard proxy host with:

  • Forward scheme: HTTP
  • Forward host: 192.168.20.10
  • Forward port: 8096
  • WebSockets: Enabled
  • Force SSL: Enabled
  • HTTP/2: Enabled
  • No custom locations
  • No advanced configuration

Is there a particular request or Nginx directive you'd like me to inspect to determine where the POST is being converted to a GET?

Have you compared your nginx setup to this: 

 

Breezey
Posted

Posted just now

I captured the Nginx Proxy Manager access log during a failed login.

The Android TV app initially sends:

POST http://xxx.xxx.xxx.com.au/emby/Users/AuthenticateByName?format=json

NPM returns 301 Moved Permanetly

The client then immediately retries as:

GET https://xxx.xxx.xxx.com.au/emby/Users/AuthenticateByName?format=json

which returns 401.

So the POST is being converted to a GET after the HTTP→HTTPS redirect.

I captured the Nginx Proxy Manager access log during the failed Android TV login.

The Android TV client appears to POST over HTTP, receives the Force SSL redirect, then retries as a GET over HTTPS, which Emby rejects.

My Nginx Proxy Manager configuration is otherwise standard with Force SSL enabled and no custom rewrite rules.

Is the Android TV client expected to start with HTTP even when the server is configured as HTTPS, or should it be connecting via HTTPS directly?

Posted
Quote

NPM returns 301 Moved Permanetly

This is not going to work. I mean you can leave it that way but it will not work like you're expecting. It will work when you put the server address in the browser address bar. That is what that kind of redirect is made for.

It's not going to work for request that aren't GET because the request method and body do not get preserved on the redirect. This is correct behavior and it's not even in our control anyway. It's happening internally in the browser or client device networking stack. For more info, read this AI-generated blurb:

Quote
When using the fetch() API, an HTTP 301 Moved Permanently status code automatically forces a non-GET request (like POST, PUT, or DELETE) to change into a GET request during the subsequent redirection follow-up. This behavior complies with the Fetch Standard specification, which converts the HTTP method to GET and strips the original request body to prevent data corruption at the new destination. [1, 2]
Why This Happens
Historically, web browsers automatically changed POST requests to GET requests upon receiving a 301 or 302 redirect status. Because this became standard practice for client applications, modern APIs and the official Fetch specification codified this exact sequence. [1, 2, 3, 4]
How to Fix or Prevent It
If you want the redirected request to keep its original HTTP method (such as POST) and preserve its payload, you can use any of the solutions below:

Use HTTP 308 instead: Change your server-side configuration to respond with a 308 Permanent Redirect instead of a 301. The 308 status code explicitly prohibits user agents from changing the request method. [1, 2]

Use HTTP 307 for temporary changes: If the redirection is not permanent, use a 307 Temporary Redirect status code. This preserves the original HTTP method and body just like a 308. [1, 2, 3]

Update your client-side target URL: Change the initial URL string inside your fetch() code to point directly to the new, final endpoint so that zero redirects occur. [1, 2]

 

 

Posted

It mentions 307 and 308, but I don't recall users mentioning that before and it's not something we've tested. Hopefully it will work.

The third option about updating your client-side url is what you want to do, and that's what I'm about to explain:

Quote

Is the Android TV client expected to start with HTTP even when the server is configured as HTTPS, or should it be connecting via HTTPS directly?

No, it will connect however you want, but you need to actually connect that way by setting up a server connection. I would guess that you initially connected over http, then setup the redirect in NPM and expected it to just work in Emby apps. You need to go back to the Emby app and do a new server connection and specify the https address if that's what you want to do.

And of course, make sure the server dashboard is displaying the https address as your remote address.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...