diff --git a/docs/simplesamlphp-sp.txt b/docs/simplesamlphp-sp.txt index 3114f1b6b193940ab48a25c92cd4fce2b7170c3f..b54441a925d547e8e5f75ae86274991b120da092 100644 --- a/docs/simplesamlphp-sp.txt +++ b/docs/simplesamlphp-sp.txt @@ -199,6 +199,17 @@ We can also request authentication with a specific IdP: Other options are also available. Take a look in the documentation for the [SP module](./saml:sp) for a list of all parameters. +If we are using PHP sessions in SimpleSAMLphp and in the application we are protecting, SimpleSAMLphp will close any +existing session when invoked for the first time, and its own session will prevail afterwards. If you want to restore +your own session after calling SimpleSAMLphp, you can do so by cleaning up the session like this: + + $session = SimpleSAML_Session::getSessionFromRequest(); + $session->cleanup(); + +If you don't cleanup SimpleSAMLphp's session and try to use $_SESSION afterwards, you won't be using your own session +and all your data is likely to get lost or inaccessible. + + Support ------- diff --git a/lib/SimpleSAML/Session.php b/lib/SimpleSAML/Session.php index d0a5214680b6c3f18f1ffb564f181f17ca617f02..b4671695251edfd67045cb533b06c9218a75b6ab 100644 --- a/lib/SimpleSAML/Session.php +++ b/lib/SimpleSAML/Session.php @@ -370,6 +370,23 @@ class SimpleSAML_Session } } + + /** + * Save the current session and clean any left overs that could interfere with the normal application behaviour. + * + * Use this method if you are using PHP sessions in your application *and* in SimpleSAMLphp, *after* you are done + * using SimpleSAMLphp and before trying to access your application's session again. + */ + public function cleanup() + { + $this->save(); + $sh = SimpleSAML_SessionHandler::getSessionHandler(); + if ($sh instanceof SimpleSAML_SessionHandlerPHP) { + $sh->restorePrevious(); + } + } + + /** * Mark this session as dirty. * diff --git a/lib/SimpleSAML/SessionHandler.php b/lib/SimpleSAML/SessionHandler.php index 8d14c0900a0a014ebcd0d465a48682bb4a12c390..23d826f53986d2b12310486c1b0fecbdead844bf 100644 --- a/lib/SimpleSAML/SessionHandler.php +++ b/lib/SimpleSAML/SessionHandler.php @@ -23,7 +23,7 @@ abstract class SimpleSAML_SessionHandler * * @var SimpleSAML_SessionHandler */ - private static $sessionHandler = null; + protected static $sessionHandler = null; /** diff --git a/lib/SimpleSAML/SessionHandlerPHP.php b/lib/SimpleSAML/SessionHandlerPHP.php index 9126eab271efae8f7b7cd65014e9823eee4180e7..09f7063734be83d869d491f3a61884732ec8a8d5 100644 --- a/lib/SimpleSAML/SessionHandlerPHP.php +++ b/lib/SimpleSAML/SessionHandlerPHP.php @@ -74,9 +74,47 @@ class SimpleSAML_SessionHandlerPHP extends SimpleSAML_SessionHandler $savepath = $config->getString('session.phpsession.savepath', null); if (!empty($savepath)) { session_save_path($savepath); + } + } + /** + * Restore a previously-existing session. + * + * Use this method to restore a previous PHP session existing before SimpleSAMLphp initialized its own session. + * + * WARNING: do not use this method directly, unless you know what you are doing. Calling this method directly, + * outside of SimpleSAML_Session, could cause SimpleSAMLphp's session to be lost or mess the application's one. The + * session must always be saved properly before calling this method. If you don't understand what this is about, + * don't use this method. + */ + public function restorePrevious() + { + if (empty($this->previous_session)) { + return; // nothing to do here } + + // close our own session + session_write_close(); + + session_name($this->previous_session['name']); + session_set_cookie_params( + $this->previous_session['cookie_params']['lifetime'], + $this->previous_session['cookie_params']['path'], + $this->previous_session['cookie_params']['domain'], + $this->previous_session['cookie_params']['secure'], + $this->previous_session['cookie_params']['httponly'] + ); + session_id($this->previous_session['id']); + $this->previous_session = array(); + session_start(); + + /* + * At this point, we have restored a previously-existing session, so we can't continue to use our session here. + * Therefore, we need to load our session again in case we need it. We remove this handler from the parent + * class so that the handler is initialized again if we ever need to do something with the session. + */ + parent::$sessionHandler = null; }