Open leshravnya opened 4 months ago
Hi @leshravnya, thanks for bringing this up.
Fastapi-sso currently does not handle any X-Forwarded*
headers, but startlette
(and fastapi
) should. Are you using request.url_for
to get your redirect uri? Could you provide a code snippet?
One of the standard solutions is to let the application know which domain it is being served on. Just add to the configuration of your domain.example.com
and specify it in redirect_uri
param.
This solution does not require middleware, but it will not work if your application is accessible from multiple domains.
I am also facing similar kind of issue, I am running my fastapi application in a k8s cluster and am using ingress-nginx for routing:
I tried to follow the example here: https://tomasvotava.github.io/fastapi-sso/tutorials/#a-minimal-example
But I am getting this error [auth] httpx.ConnectError: All connection attempts failed
when I try to navigate to: http://<domain-name>/api/auth/google/login
Here are the relevant code files: https://github.com/adityabhattad2021/medbot/blob/main/infra/k8s/ingress-service.yaml https://github.com/adityabhattad2021/medbot/blob/main/auth/requirements.txt https://github.com/adityabhattad2021/medbot/blob/main/auth/src/app.py https://github.com/adityabhattad2021/medbot/blob/main/auth/src/routes/login_with_google.py
Thankyou.
Hi @adityabhattad2021, this seems weird, because httpx is used to communicate with the oauth provider (Google in your case), I am not sure this is an issue with the proxy. Could you please provide the full traceback of the error?
I am also facing similar kind of issue, I am running my fastapi application in a k8s cluster and am using ingress-nginx for routing: I tried to follow the example here: https://tomasvotava.github.io/fastapi-sso/tutorials/#a-minimal-example But I am getting this error
[auth] httpx.ConnectError: All connection attempts failed
when I try to navigate to:http://<domain-name>/api/auth/google/login
Here are the relevant code files: https://github.com/adityabhattad2021/medbot/blob/main/infra/k8s/ingress-service.yaml https://github.com/adityabhattad2021/medbot/blob/main/auth/requirements.txt https://github.com/adityabhattad2021/medbot/blob/main/auth/src/app.py https://github.com/adityabhattad2021/medbot/blob/main/auth/src/routes/login_with_google.py
Thankyou.
This seems more of an issue with the setup itself. Try using a service type NodePort instead of a full Ingress if you're not using SSL. That way, you'll rapidly know if the library works, but it does. I should know cause I have similar setup and it works like charm: k8s, Traefik (instead of Nginx) and CertManager. For the record it used to work well 2 years ago when I was using Ingress Nginx. Hope it helps!
Hi @adityabhattad2021, this seems weird, because httpx is used to communicate with the oauth provider (Google in your case), I am not sure this is an issue with the proxy. Could you please provide the full traceback of the error?
Here:
[auth] Traceback (most recent call last):
[auth] File "/usr/local/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 407, in run_asgi
[auth] result = await app( # type: ignore[func-returns-value]
[auth] File "/usr/local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 69, in __call__
[auth] return await self.app(scope, receive, send)
[auth] File "/usr/local/lib/python3.10/site-packages/fastapi/applications.py", line 1054, in __call__
[auth] await super().__call__(scope, receive, send)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/applications.py", line 123, in __call__
[auth] await self.middleware_stack(scope, receive, send)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 186, in __call__
[auth] raise exc
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 164, in __call__
[auth] await self.app(scope, receive, _send)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 189, in __call__
[auth] with collapse_excgroups():
[auth] File "/usr/local/lib/python3.10/contextlib.py", line 153, in __exit__
[auth] self.gen.throw(typ, value, traceback)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/_utils.py", line 93, in collapse_excgroups
[auth] raise exc
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 191, in __call__
[auth] response = await self.dispatch_func(request, call_next)
[auth] File "/app/src/app.py", line 35, in dispatch
[auth] response = await call_next(request)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 165, in call_next
[auth] raise app_exc
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/middleware/base.py", line 151, in coro
[auth] await self.app(scope, receive_or_disconnect, send_no_error)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/middleware/cors.py", line 85, in __call__
[auth] await self.app(scope, receive, send)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 65, in __call__
[auth] await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
[auth] raise exc
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
[auth] await app(scope, receive, sender)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 756, in __call__
[auth] await self.middleware_stack(scope, receive, send)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 776, in app
[auth] await route.handle(scope, receive, send)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 297, in handle
[auth] await self.app(scope, receive, send)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 77, in app
[auth] await wrap_app_handling_exceptions(app, request)(scope, receive, send)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
[auth] raise exc
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
[auth] await app(scope, receive, sender)
[auth] File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 72, in app
[auth] response = await func(request)
[auth] File "/usr/local/lib/python3.10/site-packages/fastapi/routing.py", line 278, in app
[auth] raw_response = await run_endpoint_function(
[auth] File "/usr/local/lib/python3.10/site-packages/fastapi/routing.py", line 191, in run_endpoint_function
[auth] return await dependant.call(**values)
[auth] File "/app/src/routes/login_with_google.py", line 32, in callback
[auth] user = await google_sso.verify_and_process(request)
[auth] File "/usr/local/lib/python3.10/site-packages/fastapi_sso/sso/base.py", line 359, in verify_and_process
[auth] return await self.process_login(
[auth] File "/usr/local/lib/python3.10/site-packages/fastapi_sso/sso/base.py", line 494, in process_login
[auth] response = await session.post(token_url, headers=headers, content=body, auth=auth)
[auth] File "/usr/local/lib/python3.10/site-packages/httpx/_client.py", line 1892, in post
[auth] return await self.request(
[auth] File "/usr/local/lib/python3.10/site-packages/httpx/_client.py", line 1574, in request
[auth] return await self.send(request, auth=auth, follow_redirects=follow_redirects)
[auth] File "/usr/local/lib/python3.10/site-packages/httpx/_client.py", line 1661, in send
[auth] response = await self._send_handling_auth(
[auth] File "/usr/local/lib/python3.10/site-packages/httpx/_client.py", line 1689, in _send_handling_auth
[auth] response = await self._send_handling_redirects(
[auth] File "/usr/local/lib/python3.10/site-packages/httpx/_client.py", line 1726, in _send_handling_redirects
[auth] response = await self._send_single_request(request)
[auth] File "/usr/local/lib/python3.10/site-packages/httpx/_client.py", line 1763, in _send_single_request
[auth] response = await transport.handle_async_request(request)
[auth] File "/usr/local/lib/python3.10/site-packages/httpx/_transports/default.py", line 372, in handle_async_request
[auth] with map_httpcore_exceptions():
[auth] File "/usr/local/lib/python3.10/contextlib.py", line 153, in __exit__
[auth] self.gen.throw(typ, value, traceback)
[auth] File "/usr/local/lib/python3.10/site-packages/httpx/_transports/default.py", line 86, in map_httpcore_exceptions
[auth] raise mapped_exc(message) from exc
[auth] httpx.ConnectError: All connection attempts failed
This is really weird, it seems more like a network trouble, are you sure the requests can go through and are not blocked on egress?
Yes the requests do go through, I even tried to log those as well using this middleware
class LoggingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
body = await request.body()
print(f"Request body: {body.decode()}")
print(f"Request headers: {dict(request.headers)}")
print(f"Request path: {request.url.path}")
response = await call_next(request)
print(f"Response status: {response.status_code}")
return response
Happens to me as well. Deployed app on azure behind nginx and keep getting redirect uri mismatch
Actually this happens locally as well if my app is run in docker, but only if I build as linux/amd64 If I build native for my M1 Mac it works flawless
I also get {"detail":"'code' parameter was not found in callback request"}
@K1T3K1 hey, are you running your app using uvicorn
? If yes, can you confirm that you are using --root-path
as specified in the docs? Also, although hard-coded and mostly not preferred, you can specify it on your FastAPI instance
To your second problem, could you refer to #164 and preferably post debug logs so that I can further investigate 🙏
Thank you all for reaching out!
Also, always make sure that your proxies (nginx, traeffik, etc.) know that they should set Host
headers correctly. E.g. for nginx.
I am trying to deploy my app using nginx as a proxy. My
fastapi
app is running onhttp://localhost:8000
and thenginx
is listening to the public IP on port 443. I have configured theredirect_uri
for the login ashttp://localhost:8000/auth/callback
. However, after authentication from the SSO server, it redirects to thehttp://localhost:8000/auth/callback
instead of thehttps://domain.example.com/auth/callback
.I tried to change the auth URI from
http://localhost:8000/auth/callback
tohttps://domain.example.com/auth/callback
and I get the below error in the callback. I need help in resolving this issue.