Posted on 25/01/
Sometimes you just can't rely on the Apache module for what you are doing. Maybe because you are not using Apache... or maybe because you find yourself in a situation where your application runs on a separate server, and Apache is just proxying requests back to you. The backend server doesn't recieve the famous REMOTE_USER environment variable because environment isn't passed when requests are proxied. If you know a way of getting the ENV to the backend server, drop me a mail (pplu at capside.com).
So you are on your own! Just very recently the Apache::AuthTkt module got updated with a method to get info from a ticket back. That is: it used to be a one way ride: you could generate tickets, but from a ticket you couldn't get anything back, so you couldn't validate the tickets you generated (the module is supposed to do that).
Getting the application to properly handle the tickets is not that straightforward, so I'll detail what you have to do to get it (hopefully) right:
- - no ticket: Show the login screen. Verify the login screen's supplied credentials against the credential db of your choice and extend a ticket if credentials are correct. Redirect to original (protected) URL. This time you'll have a valid ticket and get past. Of course, instead of showing the login screen you can show contents for anonymous users, if you like
- - ticket expiry: when you parse the ticket you get the timestamp of the time it was generated. You have to control if it has expired (ticket.ts + seconds for which the ticket will be considered valid < now). If the ticket has expired: show the login screen
- - ticket renewal when the ticket is close to expiring your application should renew it (generate another one with a new timestamp), so suddenly the user doesn't get logged out. If you don't, your logins will only last for a maximum of expiry seconds...
- - cross domain authentication:
Take into account that the ticket can be sent instead of via cookie, via GET.
- - ticket tampering:the logged in userid, timestamp, and tokens (if any... see docs for more details) are beeing transmitted in almost clear text. So what if someone changes the data in the ticket and submits that? Luckily there is a digest field in the cookie that gets formed with: MD5(clear text info + ip address + the secret) the real implementation does more things, but this serves to make my point clear. The server can validate if any of the clear info or the IP was changed by just regenerating the digest, and comparing it to the one that was recieved in the cookie. If the expected digest doesn't match with the new digest: show the login screen.
On this last point we had a bit of a surprise. In Apache::AuthTkt you could call the new method parse_ticket, it didn't return the digest, and it didn't do the validation. So if you where relying on that method to see if the ticket was valid, you would be accepting tampered tickets. So Ton Voon and I updated the module so it would have a new method: valid_ticket that verifies the digest and only returns data if the ticket has not been tampered with. Hopefully the patch to the module will get to the CPAN Apache::AuthTkt module soon. Ticket expiry and renewal are still the applications responsibillty.
PHP and Python contributed API can not parse and validate the cookie. So if you are using those languages, take into consideration extending those contributed modules to do ticket validation.
PHP is almost always running under Apache, and if it runs under FastCGI there is no problem: it will inherit the REMOTE_USER environment variable, and you won't even notice. I suppose that python boys can rapidly implement the parse_ticket & valid_ticket methods with their eyes closed.