Invalid redirect URI in Google OAuth2 API call (http instead of https)


(Jan Philip Gehrcke) #1

My web server only allows access via https to the Discourse instance I am running. It automatically redirects http requests to https. I have set Discourse to use https via the use https setting in the Security settings category. Generally, Discourse works fine with that setting. Regarding Google OAuth, however, I needed to remove the s from the https in the allowed redirect URI setting in the Google dashboard. The redirect URI in the API call sent by Discourse has the s removed (it specifies http://... instead of https://...). Therefore the URI I originally set in the Google dashboard does not match the redirect URI provided by Discourse in the API call.

As I have set my web server to redirect from http to https, this could be worked around by removing the s in the Google dashboard. The real fix, however, would be that Discourse sends the proper redirect URI in the API call in the first place.

I reproduced that with a checkout from yesterday.


Configuring Google login for Discourse
(Jan Philip Gehrcke) #2

This is clearly related: Google Groups

Cristiano,
Try setting

OmniAuth.config.full_host = 'https://domain.com
in the omniauth initializer file (config/initializers/omniauth.rb)


(Sam Saffron) #3

Try:

hooks:
  after_web_config:
     - replace:
         filename: /etc/nginx/conf.d/discourse.conf
         from: $thescheme;
         to: https;
         global: true

If you don’t forward headers right oauth2 redirects don’t work right, recategorizing as support.


Configuring Google login for Discourse
(Jan Philip Gehrcke) #4

I understand the solution you are proposing. The proper fix, without customizing the disource.conf in the container, however, would be to inform the web application about the protocol used via an HTTP header, as you are also suggesting.

The question is: does Discourse respect/support X-Forwarded-Protocol? Then I can easily configure the nginx reverse proxy with

proxy_set_header X-Forwarded-Protocol $scheme;

Edit: I can confirm that properly setting the X-Forwarded-Proto header in the nginx reverse proxy (and SSL terminator) makes Google OAuth2 work as expected:

proxy_set_header X-Forwarded-Proto $scheme

In my case I used proxy_set_header X-Forwarded-Proto https since I enforce HTTPS anyway.

For people finding this post I should clarify that I am running Discourse through two nginx reverse proxys. One is pre-confgured in the default discourse_docker container (without SSL support by default). I made this container-internal nginx listen only on localhost of the host, i.e. it is not reachable externally (from the internet). The second nginx is running on the host (not within a Docker container) and mainly performs SSL termination and proxies all requests to the container-internal nginx.


Configuring Google login for Discourse
(Marijn Haverbeke) #5

I am still having this problem, and neither explicitly setting the OmniAuth full_host nor the X-Forwarded-Proto header (which is present in the current example nginx config) help. The URL Discourse passes to OAuth providers ends up looking like https://domain:80/..., i.e. the fact that we’re on https is picked up, but port 80 is added.

Am I doing something wrong? Can someone suggest a quick workaround?


(Sam Saffron) #6

Honored to have you around here, I am pretty confident that needs to be hard coded into the config, I usually add a hook with the text

- replace:
     filename: /etc/nginx/conf.d/discourse.conf
     from: $thescheme;
     to: https;
     global: true

(Marijn Haverbeke) #7

I’m not using Docker (I know, not supported), but I manually replaced $thescheme with https in my nginx config file.

Is this URL really being created by OmniAuth? I tried adding a log statement there, but it didn’t create any output. Do I have to regenerate any data structure after changing the OmniAuth config?


(Sam Saffron) #8

Omniauth looks at that header:

You can also try our site settings, which may help.


(Marijn Haverbeke) #9

Note that my problem isn’t that the protocol isn’t being set to https, it is that the port of that https url is set to 80. Nothing in omniauth/strategy.rb seems to be touching the port of the URL.

Is there a convenient way to add logging statements to dependency code like omniauth and have them show up in my discourse log file? I tried log :info, and though it did not break anything, I also couldn’t find its output anywhere. (I know almost nothing about Ruby, so excuse my ignorance.)


(Sam Saffron) #10

You can use Rails.logger.warn and then look in sitename/logs (as admin)


(Marijn Haverbeke) #11

There’s log/production.log, but I don’t see anything that looks like sitename/logs (the only logs directory contains templates)


(jaming) #12

I think he means yourhostname.domain/logs not a directory on the server.


(Marijn Haverbeke) #13

Ah, I see. But no, I can’t find the messages there either. Is there any resource you’d recommend about debugging a system like this? Adding log statements and restarting the server is really not working for me so far (not in the least because restarting the server seems to take a lot of time, for some reason.)


(Sam Saffron) #14

It is definitely logged there, just be sure to type Rails.logger.warn "some string" try inserting it in a few different spots to see it in action, you must restart properly after making these kinds of changes.

Another option is running in debug mode (not RAILS_ENV=development) then you get even richer error handling.

Also, really curious why is it you can not use the Docker install?


(Marijn Haverbeke) #15

I’m using a virtual server that has its kernel pinned at a too-old-for-docker kernel by the provider. Seeing how my setup is for a not-for-profit project (discuss.codemirror.net), I can’t really afford to spawn a new vm for every service I need.


(Marijn Haverbeke) #16

What would restaring properly entail? Re-run bluepill, or do I need to do something else?


(Sam Saffron) #17

Bluepill is a disaster I would not trust it, our docker setup stopped using it over a year ago

I guess I would nuke the thin/unicorn pids and hope it starts it up again or reboot


(Marijn Haverbeke) #18

Ah, I think that might explain some of my confusion. I’ll try manually killing the processes.


(Dorian) #19

@marijn, were you able to fix your issue?

We’re facing the exact same problem here—non-Docker install, added X-Forwarded-Proto header, but now Discourse tries to use https://our-site.org:80/blah as OAuth2 callback URL, which doesn’t work because nothing is listening on port 80…

Any pointers greatly appreciated!

[edit]: We managed to solve it be killing every Discourse-related process and restarting. Thanks for the valuable hints in this thread!


(Marijn Haverbeke) #20

@dorian_kind I haven’t had time to further dig into this. My setup is, embarrassingly, running as plain HTTP for the time being.