From f2c2e6ea5e4f77dd3b53f83655ffd81adc971bec Mon Sep 17 00:00:00 2001 From: Andjelko Horvat <comel@vingd.com> Date: Fri, 13 Sep 2013 11:04:39 +0000 Subject: [PATCH] Add remember me feature (patch 2 from issue #571). git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@3276 44740490-163a-0410-bde0-09ae8108e29a --- config-templates/config.php | 17 +++++++ lib/SimpleSAML/Auth/Default.php | 4 +- lib/SimpleSAML/Session.php | 85 ++++++++++++++++++++++++++++++++- 3 files changed, 101 insertions(+), 5 deletions(-) diff --git a/config-templates/config.php b/config-templates/config.php index 4a286d3fd..ca7f2e463 100644 --- a/config-templates/config.php +++ b/config-templates/config.php @@ -290,6 +290,23 @@ $config = array ( */ 'session.authtoken.cookiename' => 'SimpleSAMLAuthToken', + /* + * Options for remember me feature for IdP sessions. Remember me feature + * has to be also implemented in authentication source used. + * + * Option 'session.cookie.lifetime' should be set to zero (0), i.e. cookie + * expires on browser session if remember me is not checked. + * + * Session duration ('session.duration' option) should be set according to + * 'session.rememberme.lifetime' option. + * + * It's advised to use remember me feature with session checking function + * defined with 'session.check_function' option. + */ + 'session.rememberme.enable' => FALSE, + 'session.rememberme.checked' => FALSE, + 'session.rememberme.lifetime' => (14*86400), + /** * Custom function for session checking called on session init and loading. * See docs/simplesamlphp-advancedfeatures.txt for function code example. diff --git a/lib/SimpleSAML/Auth/Default.php b/lib/SimpleSAML/Auth/Default.php index de5873c8a..39cc174f3 100644 --- a/lib/SimpleSAML/Auth/Default.php +++ b/lib/SimpleSAML/Auth/Default.php @@ -91,7 +91,7 @@ class SimpleSAML_Auth_Default { } /* Add those that should always be included. */ - foreach (array('Attributes', 'Expire', 'LogoutState', 'AuthnInstant') as $a) { + foreach (array('Attributes', 'Expire', 'LogoutState', 'AuthnInstant', 'RememberMe') as $a) { if (isset($state[$a])) { $persistentAuthState[$a] = $state[$a]; } @@ -255,5 +255,3 @@ class SimpleSAML_Auth_Default { } } - -?> \ No newline at end of file diff --git a/lib/SimpleSAML/Session.php b/lib/SimpleSAML/Session.php index b7151a98b..404b54819 100644 --- a/lib/SimpleSAML/Session.php +++ b/lib/SimpleSAML/Session.php @@ -80,7 +80,9 @@ class SimpleSAML_Session { // Session duration parameters private $sessionstarted = null; private $sessionduration = null; - + + private $rememberMeExpire = null; + // Track whether the session object is modified or not. private $dirty = false; @@ -500,6 +502,52 @@ class SimpleSAML_Session { } + /** + * Set remember me expire time. + * + * @param int $expire Unix timestamp when remember me session cookies expire. + */ + public function setRememberMeExpire($expire = NULL) { + assert('is_int($expire) || is_null($expire)'); + + if ($expire === NULL) { + $globalConfig = SimpleSAML_Configuration::getInstance(); + $expire = time() + $globalConfig->getInteger('session.rememberme.lifetime', 14*86400); + } + $this->rememberMeExpire = $expire; + + $cookieParams = array('expire' => $this->rememberMeExpire); + $this->updateSessionCookies($cookieParams); + } + + + /** + * Get remember me expire time. + * + * @return integer|NULL The remember me expire time. + */ + public function getRememberMeExpire() { + return $this->rememberMeExpire; + } + + + /** + * Update session cookies. + */ + public function updateSessionCookies($params = NULL) { + $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); + + if ($this->sessionId !== NULL) { + $sessionHandler->setCookie($sessionHandler->getSessionCookieName(), $this->sessionId, $params); + } + + if ($this->authToken !== NULL) { + $globalConfig = SimpleSAML_Configuration::getInstance(); + $sessionHandler->setCookie($globalConfig->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'), $this->authToken, $params); + } + } + + /** * Marks the user as logged in with the specified authority. * @@ -526,6 +574,8 @@ class SimpleSAML_Session { $data = array(); } + $data['Authority'] = $authority; + $globalConfig = SimpleSAML_Configuration::getInstance(); if (!isset($data['AuthnInstant'])) { $data['AuthnInstant'] = time(); @@ -542,7 +592,12 @@ class SimpleSAML_Session { $this->authToken = SimpleSAML_Utilities::generateID(); $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); - $sessionHandler->setCookie($globalConfig->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'), $this->authToken); + + if (!$this->transient && (!empty($data['RememberMe']) || $this->rememberMeExpire) && $globalConfig->getBoolean('session.rememberme.enable', FALSE)) { + $this->setRememberMeExpire(); + } else { + $sessionHandler->setCookie($globalConfig->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken'), $this->authToken); + } } @@ -578,11 +633,37 @@ class SimpleSAML_Session { $this->authority = NULL; } + if ($this->authority === NULL && $this->rememberMeExpire) { + $this->rememberMeExpire = NULL; + $this->updateSessionCookies(); + } + /* Delete data which expires on logout. */ $this->expireDataLogout(); } + /** + * Set the lifetime for authentication source. + * + * @param string $authority The authentication source we are setting expire time for. + * @param int $expire The number of seconds authentication source is valid. + */ + public function setAuthorityExpire($authority, $expire = NULL) { + assert('isset($this->authData[$authority])'); + assert('is_int($expire) || is_null($expire)'); + + $this->dirty = true; + + if ($expire === NULL) { + $globalConfig = SimpleSAML_Configuration::getInstance(); + $expire = time() + $globalConfig->getInteger('session.duration', 8*60*60); + } + + $this->authData[$authority]['Expire'] = $expire; + } + + /** * Set the lifetime of our current authentication session. * -- GitLab