Jinx wrote:
Great to hear things are working, means we designed it properly :)
Unfortunately I think I've found a problem that I can't get around.
If you recall, I mentioned that an HTTP Kerberos SSO authentication is actually two requests. The first request is rejected with a 401 and a special header. That triggers the client to re-submit the request with a base 64 encoded token.
Ideally, the first request should be intercepted before anything else. It should literally be the first thing executed by the script. But as you know that's not possible with the current code. The earliest opportunity for a plugin to act is in the onAfterInitialise event.
Currently when the onAfterInitialise handler of our SSO plugin needs to reject with a 401, we call die() because we do not want to send any unnecessary content in the body and we want the script to perform as little processing as possible.
Unfortunately calling die() in onAfterInitialise causes a problem with sessions. This is reproducible when someone clicks 'Logout'. In this case the session is destroyed and a redirect is sent to the client. The subsequent request is received, the session initialization code runs, a default JUser is placed into the session and, as usual, the onAfterInitialise handler rejects the request with 401 and calls die().
This is where the problem occurs. The client re-submits the request with the auth token but when onAfterInitialise is called JFactory:getUser returns NULL because $session->get('user') is not defined.
I'm not sure exactly why it's not set but apparently after the default JUser is set the die() call screws it up. I guess the die() call prevented the session from being saved properly.
If I remove the die() call the SSO filter works. However, it sends the client the entire page even though we're just sending a 401 Unauthorized. Meaning for each request the page is rendered twice. That's not ok.
There really needs to be a hook at line 0 of index.php. That was true before I ran into this problem. Obviously you can't use your existing plugins and events infrastructure to do that but you could create a special plugins directory called 'start' something like that that simply calls a function of a predefined name found in files in that directory. For example I would have a file:
plugins/start/plexcel.php
This would be loaded and the function named 'plexcel_start' would be called. In my case this function would check apache_request_headers for the authentication token. If present it set's the status to 401 and calls die(). If it is present it does nothing and the real work is performed in onAfterInitialise as usual.
If this solution would be acceptable I would be more than happy to provide the implementation. It would all be very simple I think.
Otherwise, doing Kerberos or NTLM or any other mutli-request HTTP authentication protocol in J! is going to be so slow I would have no other choice but to require users to patch J! before they can use our plugin. That would not go over well.
Mike