Need ability to set URL's in SAML XML to different hostname

Issue #4 resolved
Jay Tuckey created an issue

Hi Guys,

Love this project, it has made integrating into my SAML server at work much easier from my Flask app.

However, I ran into issues trying to get the URL's in the metadata XML to match, when I run my app behind a reverse proxy. For example: For dev: Running app on https://localhost:5000 I need entityID="https://localhost:5000/saml/metadata/" and Location="https://localhost:5000/saml/acs/"

For prod, running app on a web server under port 8000, then reverse proxied to be under URL example.cdu.edu.au: I need entityID="https://example.cdu.edu.au/saml/metadata/" and Location="https://example.cdu.edu.au/saml/acs/"

However, in this situation, Flask still believes it's running on "https://webserver1.cdu.edu.au" so that's what the URL's in the SAML metadata are set to.

This can be fixed with a few lines in the library, by adding a SAML_CUSTOM_SERVER_NAME config. I have made a version of the fix I propose here: https://bitbucket.org/WalrusTusks/flask_saml/commits/659b2a637a7861de158f2f426d2486420fe77ee4

Let me know if you would like anything further from me, or if I can help implement this in any way.

Regards Jay

Comments (5)

  1. Justin Ferguson

    I need this capability as well - I'm running my app behind an nginx proxy and the ACS url that's being returned is the internal name and not the public-facing address.

  2. George Mauer

    I was able to get around this like so

    import flask
    from functools import wraps
    
    
    def url_for_with_proper_server_redirect(f):
    
        @wraps(f)
        def inner(*args, **kwargs):
            url = f(*args, **kwargs)
    
            if kwargs.get('_external'):
                url = url.replace('server:5000', 'localhost:3000')
    
            return url
    
        return inner
    
    
    flask.url_for = url_for_with_proper_server_redirect(flask.url_for)
    
    
    def initialize_saml(app):
        from flask_saml import FlaskSAML
        FlaskSAML(app)
    

    If there is interest from the flask_saml team I can submit a PR that would put this into a configuration. Though also, as I'm not a python dev it might be someone more familiar with idiomatic python to take the reigns.

    I'll note that the reverse proxy scenario is not that crazy. Its actually the standard way of working nowadays with create-react-app in development, which in turn is the standard for new React applications

  3. Kevin Fleming Account Deactivated

    This is solvable without any custom code at all. If your reverse proxy is setup properly, it will inject HTTP headers indicating the original scheme, host name, port number, etc. You can then use a ProxyFix module to correct the behavior of the WSGI server in Flask. Documentation is here:

    http://flask.pocoo.org/docs/1.0/deploying/wsgi-standalone/#proxy-setups

    I just did this and the metadata produced by Flask-SAML now contains the proper URLs.

  4. Russell Jackson

    There's a similar issue in that the entityID should not be based on the hostname of application. The entityID should be immutable (hell, it doesn't even have to be a URL). For example, we issue entityID's to with the scheme of https://metadata.my.org/shibboleth/<entity-name>. If the ACS endpoints change, the metadata gets updated to reflect that, but the entityID does not change. In short, the actual run time configuration shouldn't depend on the metadata contents or vice versa.

  5. Log in to comment