Search code examples
pythonnginxreverse-proxysaml-2.0python-social-auth

SAML2 Service Provider on non standard port behind a reverse proxy


I have a SAML2 service provider (Open edX Platform if it makes a difference), configured according to docs and otherwise working normally. It runs at http://lms.local:8000 and works just fine with TestShib test Identity Provider and other 3rd party providers.

Problems begin when nginx reverse proxy is introduced. The setup is as follows:

  1. nginx, obviously, runs on port 80
  2. LMS (the service provider) runs on port 8000
  3. lms.local is aliased to localhost via hosts file

Nginx have the following site config:

server {
    listen 80;

    server_name lms.local;

    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;

        if ($request_method = 'OPTIONS') {
            return 204;
        }
    }
}

The problem is the following: python-social-auth detects that the server runs on lms.local:8000 (via request.META['HTTP_PORT']). So, if an attempt was made to use SAML SSO via the nginx proxy, it fails with the following message:

Authentication failed: SAML login failed: ['invalid_response'] (The response was received at http://lms.local:8000/auth/complete/tpa-saml/ instead of http://lms.local/auth/complete/tpa-saml/)

If that helps, an exception that causes this message is thrown in python-saml.OneLogin_Saml2_Response.is_valid.

The questions is: is that possible to run SP behind a reverse proxy on the same domain, but on different port? Shibboleth wiki says it is totally possible to run a SP behind the reverse proxy on different domain, but says nothing about ports.


Solution

  • In this particular case reverse proxy was sending X-Forwarded-Host and X-Forwarded-Port headers, so I just modified django strategy to use those values instead of what Django provides (i.e. request.get_host and request.META['SERVER_PORT']), which yielded two pull requests: