Shared sign-on across web applications
Posted by Graham Stratton Fri, 25 May 2007 16:35:00 GMT
I’ve spent the day on what I can only assume is a really common problem with a distinct lack of a solution.
We have a number of web applications, some Zope-based and also a Pylons app served using the Paste server. We are using Apache as a proxy in front of all of them.
We’d like users to be able to sign in to any of those applications and then access any of the others. To implement their security the applications will need to know what groups the user is a member of.
To complicate matters slightly, users need to be authenticated by NLTM if possible, failing that looked up in an LDAP directory, and if that fails verified against a relational database. For NTML users we’ll need to get the groups out at some point, presumably from LDAP.
Each of the applications will have its own way of keeping track of whether the user is logged in, probably by means of a cookie.
I think there are a few potential ways of sharing the sign-on information, given the restrictions of HTTP:
1) Something similar to OpenID, maybe actually using the OpenID protocol. Write a server which the web applications redirect to if authorization fails for some request. There are OpenID interfaces for plone and AuthKit. But there is a question as to whether the OpenID spec would allow returning of the list of groups a user belongs to.
2) Have the proxying Apache authenticate users and put this information in the environment. This would work if we only wanted to protect whole directories. An Apache module to help with this is mod_auth_tkt, which does rather more. Unfortunately it still doesn’t allow you to redirect users when authorization is required. What is needed is some way of catching a 401, as is done by AuthKit, and providing a sign-on there.
What I think mod_auth_tkt does is to hash the username with a secret code and store it in a cookie. The secret code is share between all the applications. If the browser sends a request claiming to be fred and hashing ‘fred’ with the secret code produces the code passed by the browser, the app1 can conclude that app2 successfully authenticated fred and gave him the code. This is really quite neat and I wouldn’t have thought of it.
3) Use paste.proxy as an extra proxy layer. This makes it easy to add middleware which will intercept status 401 messages and replace them with a login form. Since the proxy would not have a session, it would have to use set cookies in the same way as mod_auth_tkt to communicate user verification.
The problem is further complicated by external and internal Apache instances. The internal one proxies services mainly used internally, and only accepts requests which come either from machines internally of from the external Apache instance. The external one proxies the organisational website, and also allows external access to the internal services.

your comment on mod_auth_tkt ‘Unfortunately it still doesn’t allow you to redirect users when authorization is required.’ is wrong.
you can specify a mod_auth_tkt directive in apache conf file like the following:
TKTAuthLoginURL http://www.example.com/login
which will redirect user to login if the url is protected.