Trouble connecting drupal and discourse

Hi,

Let me share our implementation of SSO based on Drupal 7.56 and Discourse 1.9.0.beta7 using discourse_sso plugin. I have tried the plugin on the subject, even OAuth2 integration but the most interesting were this one. Unfortunately, there is no enough information how to force SSO to run, even Readme does not contain useful information. For that reason, I decided to publish my live configuration.

SSO Drupal Discourse

The configuration is:

Ubuntu 16.04.1 x86_64
Nginx/1.10.3
Docker 17.06.1-ce
Discourse 1.9.0.beta7
Drupal 7.56
Php v7.0.22
Discourse_sso (from github)

On test environment, both services, Discourse and Drupal are located on the same server as virtual servers managed by Nginx. Both services are managed by two separate config files (see below). The sources how to install Discourse and Drupal are here and here.

I have to mention that Discourse is the main service in our case (because Drupal is more flexible to tune), it uses port 80. But as desired by our team, the forum has moved from root (/) folder to /support folder. The guide I used for this is located here but the settings are described below as well.

Next, Drupal website operates on port 8080 on the same server.

Forum URL: http://example.com/support
Drupal site URL: http://example.com:8080

Config for Drupal /etc/nginx/sites-enabled/drupal:

server {
        listen 8080 default_server;
        root /var/www/html/drupal;
        server_name example.com;
 
        location / {
                # This line and below allow to use clean links
                try_files $uri /index.php?$query_string;
        }
 
        location @rewrite {
                rewrite ^/(.*)$ /index.php?q=$1;
        }
 
        location ~ ^/sites/.*/files/styles/ {
                try_files $uri @rewrite;
        }
 
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        }
 
}

Enable clean URLs in Drupal: Configuration - Search and metadata (block) - Clean URLs - Enable clean URLs

To disable a blank screen on root folder apply redirection definition into Nginx config for Discourse:
Config for Discourse /etc/nginx/sites-enabled/discourse:

server {
        listen 80;
        server_name forum.example.com;
 
        location /support {
                proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
                proxy_set_header Host $http_host;
                proxy_http_version 1.1;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
        }
 
        # Forward requests from Discourse root to Drupal root 
        location / {
                proxy_pass http://127.0.0.1:8080;
#               proxy_redirect off;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_read_timeout 30m;
        }
}

Some additional settings to Discourse app.yml:
Add a line to templates:

   templates:
   - "templates/web.socketed.template.yml"  # <-- Added

Comment a line answering for the port 80 redirection:

expose:
# - "80:80"    # http

Add to ‘env’ section:
DISCOURSE_RELATIVE_URL_ROOT: /support
version: 1.9.0.beta7

Modify your ‘run’ section (completely view):

run:
    - exec:
        cd: $home
        cmd:
          - mkdir -p public/support
          - cd public/support && ln -s ../uploads && ln -s ../backups
    - replace:
       global: true
       filename: /etc/nginx/conf.d/discourse.conf
       from: proxy_pass http://discourse;
       to: |
          rewrite ^/(.*)$ /support/$1 break;
          proxy_pass http://discourse;
    - replace:
       filename: /etc/nginx/conf.d/discourse.conf
       from: etag off;
       to: |
          etag off;
          location /support/ {
             rewrite ^/support/?(.*)$ /$1;
          }
    - replace:
         filename: /etc/nginx/conf.d/discourse.conf
         from: $proxy_add_x_forwarded_for
         to: $http_fastly_client_ip
         global: true
    - exec:
         cmd:
           - sed -i '/no-referrer-when-downgrade/a proxy_redirect http:\/\/example.com\/ \/support\/;' /etc/nginx/conf.d/discourse.conf

Configure your discourse_sso plugin, download
discourse_sso.tar.gz (129.1 KB)

190

Fill Discourse site URL with your Discourse URL (our case: http://example.com/support).
Fill SSO secret with your secret token.

Go to your Discourse forum as admin and set the following options:

enable sso - enabled
sso url - <your Drupal URL + /discourse/sso> (example: http://example.com:8080/discourse/sso, this address should not return 404!)
sso secret - fill the same secret token as used above in Drupal.

Open your forum in private browser and click ‘Login’. If above settings were configured properly, you will be redirected to Drupal site. Enter your credentials and next second you will be redirected back to the forum.

p.s. After applying settings you are not allowed to login locally using your credentials. To prevent lost connection to your forum use private browsing and do not close admin settings, use /users/admin-login to login. If something went wrong, follow the instruction how to disable SSO using rails commands:

cd /var/discourse
./launcher enter app
rails c
irb > SiteSetting.enable_sso = false
irb > SiteSetting.enable_local_logins = true
irb > exit
exit

p.p.s. Disable option ‘email editable’ in Discourse admin settings to prevent using a single Drupal account to recreate Discourse user if the email was changed by a user.

5 Likes