jat255 / strava-to-fittrackee

Connector to pull workouts from a Strava account and upload them to a FitTrackee instance
MIT License
11 stars 2 forks source link

OAuth 2 MUST utilize https Error #1

Closed chrisf4lc0n closed 1 year ago

chrisf4lc0n commented 2 years ago

I am running the FitTrackee in Docker behind Apache reverse proxy and the Strava authorization side works perfectly fine, but when I am trying to "Authorize" the Strava app within the FitTrackee I keep getting this error: authlib.oauth2.rfc6749.errors.InsecureTransportError: insecure_transport: OAuth 2 MUST utilize https. I have tried to manually edit the generated urls to point to my FitTrackee instance from "self.host", but it did not make any difference.

jat255 commented 2 years ago

That looks like it's coming from the requests-oauthlib package. What did you use as the callback URL when you set up the 3rd party app in FitTrackee? I think that has to be https (if this fixes it, I'll update the readme). This is what mine looks like:

image

chrisf4lc0n commented 2 years ago

Thanks for taking your time in looking into it. The current configuration is: FitTrackee: Application URL: https://my.domain.co.uk Redirect URL: https://my.domain.co.uk/callback Strava side is fine with no issues, it gets me to the authorization FitTrackee instance with the following URL: https://my.domain.co.uk/profile/apps/authorize?response_type=code&client_id=xxx&redirect_uri=https%3A%2F%2Fmy.domain.co.uk%2Fcallback&scope=workouts%3Aread+workouts%3Awrite&state=xxx but then when when I hit "Authorize" it gives me: Error. Please try again or contact the administrator.

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 2091, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.10/site-packages/werkzeug/middleware/proxy_fix.py", line 187, in __call__
    return self.app(environ, start_response)
  File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 2076, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1519, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1517, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1503, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/usr/src/app/fittrackee/oauth2/resource_protector.py", line 76, in decorated
    return f(auth_user, *args, **kwargs)
  File "/usr/src/app/fittrackee/oauth2/routes.py", line 557, in authorize
    response = authorization_server.create_authorization_response(
  File "/usr/local/lib/python3.10/site-packages/authlib/oauth2/rfc6749/authorization_server.py", line 248, in create_authorization_response
    request = self.create_oauth2_request(request)
  File "/usr/local/lib/python3.10/site-packages/authlib/integrations/flask_oauth2/authorization_server.py", line 73, in create_oauth2_request
    return create_oauth_request(request, OAuth2Request)
  File "/usr/local/lib/python3.10/site-packages/authlib/integrations/flask_helpers.py", line 25, in create_oauth_request
    return request_cls(request.method, url, body, request.headers)
  File "/usr/local/lib/python3.10/site-packages/authlib/oauth2/rfc6749/wrappers.py", line 30, in __init__
    InsecureTransportError.check(uri)
  File "/usr/local/lib/python3.10/site-packages/authlib/oauth2/rfc6749/errors.py", line 56, in check
    raise cls()
authlib.oauth2.rfc6749.errors.InsecureTransportError: insecure_transport: OAuth 2 MUST utilize https.
jat255 commented 2 years ago

Huh, looking at the traceback, it appears this error is coming from the FitTrackee app itself (not the strava-to-fittrackee) code, since it's an error in the Flask app. If was coming from strava-to-fittrackee, I'd expect to see s2f.py (in particular the FitTrackeeConnector.auth() method) in the traceback, which I don't.

strava-to-fittrackee is designed (maybe I should have made this more clear in the README) to be run independently from FitTrackee (as in, not in the same Python environment). I have mine in a separate python virtualenv. Is there any chance you installed this in the same environment, and maybe that caused an issue? (just grasping for straws, not sure that would actually be a problem).

The only other debugging I can think to do would be to install this extension: https://rcfed.com/Browser/Tracer and look at the content of the requests/responses and figure out why something is using http:// rather than https:// (which is what the error sounds like). Here are the two requests that I see on my browser using that extension:

image

The top one is the one going TO FitTrackee that is made when you copy/paste or click the link presented in the terminal. The second is the one FROM FitTrackee to whatever you put as the callback URL (in my case https://192.X.X.X/callback) in the app definition, after you click the "Authorize" button. My guess is that there's something wrong with generating that request in your case. In my case, the redirect_uri in the first request (https://self.host/callback) and the callback URL in the app definition don't match, but that hasn't seemed to cause any issues.

jat255 commented 2 years ago

I am running the FitTrackee in Docker behind Apache reverse proxy

This is the other part that makes me wonder if it's the source of the issue. As far as FitTrackee is concerned, the app is running without SSL, and the OAuth specification states that it must use SSL. Looking into this, I see some suggestions in some other issues about setting an environment variable that disables this check (although that doesn't sound super satisfying, if you're okay with that security stance, it might be a solution):

You can run the extension to connect to a OAuth2 server using HTTP, or to a server using an invalid certificate (e.g. a self-signed one), by editing the file /etc/apache2/envvars and adding the following environment variable, or directly exporting the variable in the shell if you are executing development server with "paster serve ..." : export OAUTHLIB_INSECURE_TRANSPORT=True

Paging @SamR1, since this actually sounds like a FitTrackee issue that any third-party app would face. Have you seen this issue registering third-party apps with FitTrackee behind a reverse proxy for SSL?

jat255 commented 2 years ago

I also saw this in the FitTrackee docs for third party apps (https://samr1.github.io/FitTrackee/apps.html#resources). Not sure if it would help:

image

I ignored it originally as I'm not running behind a proxy. It looks like this header is for forwarding the original protocol (i.e. http or https). That syntax is for nginx, but you could try setting your Apache config to do the same: https://webmasters.stackexchange.com/a/107445

chrisf4lc0n commented 2 years ago

I also saw this in the FitTrackee docs for third party apps (https://samr1.github.io/FitTrackee/apps.html#resources). Not sure if it would help:

image

I ignored it originally as I'm not running behind a proxy. It looks like this header is for forwarding the original protocol (i.e. http or https). That syntax is for nginx, but you could try setting your Apache config to do the same: https://webmasters.stackexchange.com/a/107445

This indeed helped, but only partially. I added:

RequestHeader set X-Forwarded-Proto "https"
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}

to my Apache config, and it worked, but I encountered another error... I will investigate further...

chrisf4lc0n commented 1 year ago

All good now. It took me a while to get back to it, as I lost my laptop and a few other things have been happening, but I can confirm now that re-pairing all works as expected. Thank you so much for your time!