dash-auth icon indicating copy to clipboard operation
dash-auth copied to clipboard

Should Callback respect X-Forwarded-Prefix headers from reverse proxy?

Open geophpherie opened this issue 1 year ago • 1 comments

Could totally be my own inexperience here, but I'm running into redirect issues from my IDP and I think it's because of this line.

https://github.com/plotly/dash-auth/blob/18f66d308943c8bda792e22d3e697414cd36a1c3/dash_auth/oidc_auth.py#L277C9-L277C73

My nginx config has an app running on http://127.0.0.1:8050 being accessed through location /my-app1/. So I pass a proxy_set_header X-Forwarded-Prefix /my-app1.

All the auth stuff works out, however the final redirect pushes me to <my-domain> instead of <my-domain>/my-app1 like I would expect. I believe this is because I am not setting url_base_pathname in Dash to be /my-app1/, rather I am only setting requests_pathname_prefix to that value. The reason there being ... unclear .. but I find things only work when setting requests_pathname_prefix vs url_base_pathname

I'm also using a ProxyFix, which is forwarding on that Prefix header, but I am not familiar enough with Flask internals to know where / when it is applied (if at all). app.server.wsgi_app = ProxyFix( app.server.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1 )

Either way, if I patch

return redirect(self.app.config.get("url_base_pathname") or "/")

to effectively be

return redirect(request.headers.get("X-Forwarded-Prefix") or self.app.config.get("url_base_pathname") or "/")

Everything appears to redirect as intended. So I'm wondering if that header needs to be captured in this return statement.

It's no doubt a bit confusing when you have nginx waitress flask and dash all in line trying to be helpful!

geophpherie avatar Nov 21 '24 22:11 geophpherie

To accomplish the same thing w/o editing the package code you can also override the callback method.

class OIDCAuth(oidc_auth.OIDCAuth):
    def callback(self, *args, **kwargs):
        res = super().callback(*args, **kwargs)

        if prefix := request.headers.get("X-Forwarded-Prefix"):
            return redirect(prefix)
        else:
            return res

geophpherie avatar Nov 22 '24 17:11 geophpherie