views:

271

answers:

3

I'm designing a site. It is in a very early stage, and I have to make a decision whether or not to use a SingleSignOn service provided by the server. (it's a campus site, and more and more sites are using SSO here, so generally it's a good idea). The target platform is most probably going to be django via mod_wsgi. However, any documentation provided with this service features php code. This method heavily relies on using custom $_SERVER['HTTPsomething'] variables. Unfortunately, right now I don't have access to this environment.

(How) can I access these custom variables in django? According the the WSGI documentation, the environ variable should contain as many as possible variables. Can I be sure that I can access them?

A: 

Well, $_SERVER is PHP. You are likely to be able to access the same variables via WSGI as well, but to be sure you need to figure out exactly how the SSO works, so you know what creates these variables (probably Apache) and that you can access them.

Or, you can get yourself access and try it out. :)

Lennart Regebro
+3  A: 

In Django, the server environment variables are provided as dictionary members of the META attribute on the request object - so in your view, you can always access them via request.META['foo'] where foo is the name of the variable.

An easy way to see what is available is to create a view containing assert False to trigger an error. As long as you're running with DEBUG=True, you'll see a nice error page containing lots of information about the server status, including a full list of all the request attributes.

Daniel Roseman
+2  A: 

To determine the set of variables passed in the raw WSGI environment, before Django does anything to them, put the following code in the WSGI script file in place of your Django stuff.

import StringIO

def application(environ, start_response):
    headers = []
    headers.append(('Content-type', 'text/plain'))

    start_response('200 OK', headers)

    input = environ['wsgi.input']
    output = StringIO.StringIO()

    keys = environ.keys()
    keys.sort()
    for key in keys:
        print >> output, '%s: %s' % (key, repr(environ[key]))
    print >> output

    length = int(environ.get('CONTENT_LENGTH', '0'))
    output.write(input.read(length))

    return [output.getvalue()]

It will display back to the browser the set of key/value pairs.

Finding out how the SSO mechanism works is important. If it does the sensible thing, you will possibly find that it sets REMOTE_USER and possibly AUTH_TYPE variables. If REMOTE_USER is set it is an indicator that the user named in the variable has been authenticated by some higher level authentication mechanism in Apache. These variables would normally be set for HTTP Basic and Digest authentication, but to work with as many systems as possible, a SSO mechanism, should also use them.

If they are set, then there is a Django feature, described at:

http://docs.djangoproject.com/en/dev/howto/auth-remote-user/

which can then be used to have Django accept authentication done at a higher level.

Even if the SSO mechanism doesn't use REMOTE_USER, but instead uses custom headers, you can use a custom WSGI wrapper around the whole Django application to translate any custom headers to a suitable REMOTE_USER value which Django can then make use of.

Graham Dumpleton
Thank you, this was very informative.
Tamás Szelei