Skip to content
Snippets Groups Projects
Commit 8d70e31b authored by Andreas Åkre Solberg's avatar Andreas Åkre Solberg
Browse files

More efficient session usage. Now caching only assoc array for values from...

More efficient session usage. Now caching only assoc array for values from logout request. Also implemented a clean() function to call after successfully logged out.


git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@205 44740490-163a-0410-bde0-09ae8108e29a
parent 54b647e0
No related branches found
No related tags found
No related merge requests found
<?php <?php
require_once('SimpleSAML/Configuration.php');
require_once('SimpleSAML/Utilities.php');
require_once('SimpleSAML/Session.php');
require_once('SimpleSAML/SessionHandler.php');
require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php');
require_once('SimpleSAML/XML/AuthnResponse.php');
/** /**
* The Session class holds information about a user session, and everything attached to it. * The Session class holds information about a user session, and everything attached to it.
* *
...@@ -8,22 +16,9 @@ ...@@ -8,22 +16,9 @@
* Single-Log-Out. * Single-Log-Out.
* *
* @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> * @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
* @package simpleSAMLphp
* @version $Id$ * @version $Id$
*/ */
require_once('SimpleSAML/Configuration.php');
require_once('SimpleSAML/Utilities.php');
require_once('SimpleSAML/Session.php');
require_once('SimpleSAML/SessionHandler.php');
require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php');
require_once('SimpleSAML/XML/SAML20/AuthnRequest.php');
require_once('SimpleSAML/XML/AuthnResponse.php');
require_once('SimpleSAML/Bindings/SAML20/HTTPRedirect.php');
/**
* A class representing a session.
*/
class SimpleSAML_Session { class SimpleSAML_Session {
const STATE_ONLINE = 1; const STATE_ONLINE = 1;
...@@ -47,16 +42,13 @@ class SimpleSAML_Session { ...@@ -47,16 +42,13 @@ class SimpleSAML_Session {
* This is mostly used at the Shib and SAML 2.0 IdP side, at the SSOService endpoint. * This is mostly used at the Shib and SAML 2.0 IdP side, at the SSOService endpoint.
*/ */
private $authnrequests = array(); private $authnrequests = array();
private $idp = null;
private $logoutrequest = null; private $logoutrequest = null;
private $idp = null;
private $authenticated = null; private $authenticated = null;
private $protocol = null; private $protocol = null;
private $attributes = null; private $attributes = null;
private $sessionindex = null; private $sessionindex = null;
private $nameid = null; private $nameid = null;
private $nameidformat = null; private $nameidformat = null;
...@@ -67,6 +59,7 @@ class SimpleSAML_Session { ...@@ -67,6 +59,7 @@ class SimpleSAML_Session {
private $sessionstarted = null; private $sessionstarted = null;
private $sessionduration = null; private $sessionduration = null;
// Track whether the session object is modified or not.
private $dirty = false; private $dirty = false;
...@@ -138,11 +131,18 @@ class SimpleSAML_Session { ...@@ -138,11 +131,18 @@ class SimpleSAML_Session {
/**
* Get a unique ID that will be permanent for this session.
* Used for debugging and tracing log files related to a session.
*/
public function getTrackID() { public function getTrackID() {
return $this->trackid; return $this->trackid;
} }
// *** SP list to be used with SAML 2.0 SLO ***
// *** *** *** *** *** *** *** *** *** *** ***
public function add_sp_session($entityid) { public function add_sp_session($entityid) {
$this->sp_at_idpsessions[$entityid] = self::STATE_ONLINE; $this->sp_at_idpsessions[$entityid] = self::STATE_ONLINE;
} }
...@@ -173,8 +173,6 @@ class SimpleSAML_Session { ...@@ -173,8 +173,6 @@ class SimpleSAML_Session {
return $list; return $list;
} }
public function set_sp_logout_completed($entityid) { public function set_sp_logout_completed($entityid) {
$this->dirty = true; $this->dirty = true;
$this->sp_at_idpsessions[$entityid] = self::STATE_LOGGEDOUT; $this->sp_at_idpsessions[$entityid] = self::STATE_LOGGEDOUT;
...@@ -186,6 +184,7 @@ class SimpleSAML_Session { ...@@ -186,6 +184,7 @@ class SimpleSAML_Session {
error_log('Dump sp sessions: ' . $entityid . ' status: ' . $sp); error_log('Dump sp sessions: ' . $entityid . ' status: ' . $sp);
} }
} }
// *** --- ***
...@@ -244,19 +243,9 @@ class SimpleSAML_Session { ...@@ -244,19 +243,9 @@ class SimpleSAML_Session {
} }
/*
public function setAuthnResponse(SimpleSAML_XML_AuthnResponse $xml) {
throw new Exception('setAuthnResponse deprecaed'));
$this->authnresponse = $xml;
}
public function getAuthnResposne() {
throw new Exception('getAuthnResponse deprecaed'));
return $this->authnresponse;
}
*/
public function setIdP($idp) { public function setIdP($idp) {
$this->dirty = true; $this->dirty = true;
$this->idp = $idp; $this->idp = $idp;
...@@ -265,14 +254,22 @@ class SimpleSAML_Session { ...@@ -265,14 +254,22 @@ class SimpleSAML_Session {
return $this->idp; return $this->idp;
} }
public function setLogoutRequest(SimpleSAML_XML_SAML20_LogoutRequest $lr) {
public function setLogoutRequest($requestcache) {
$this->dirty = true; $this->dirty = true;
$this->logoutrequest = $lr; $this->logoutrequest = $requestcache;
} }
public function getLogoutRequest() { public function getLogoutRequest() {
return $this->logoutrequest; return $this->logoutrequest;
} }
public function setSessionIndex($sessionindex) { public function setSessionIndex($sessionindex) {
$this->dirty = true; $this->dirty = true;
...@@ -297,7 +294,8 @@ class SimpleSAML_Session { ...@@ -297,7 +294,8 @@ class SimpleSAML_Session {
} }
public function setAuthenticated($auth) { public function setAuthenticated($auth) {
$this->dirty = ($auth || ($this->authenticated != $auth)); if ($auth === false) $this->dirty = false;
if ($auth != $this->authenticated) $this->dirty = false;
$this->authenticated = $auth; $this->authenticated = $auth;
if ($auth) { if ($auth) {
$this->sessionstarted = time(); $this->sessionstarted = time();
...@@ -361,7 +359,25 @@ class SimpleSAML_Session { ...@@ -361,7 +359,25 @@ class SimpleSAML_Session {
$this->dirty = true; $this->dirty = true;
$this->attributes[$name] = $value; $this->attributes[$name] = $value;
} }
/**
* Clean the session object.
*/
public function clean() {
$this->authnrequests = array();
$this->logoutrequest = null;
$this->idp = null;
$this->authenticated = null;
$this->protocol = null;
$this->attributes = null;
$this->sessionindex = null;
$this->nameid = null;
$this->nameidformat = null;
$this->sp_at_idpsessions = array();
}
/** /**
* Is this session modified since loaded? * Is this session modified since loaded?
......
...@@ -14,7 +14,6 @@ require_once('xmlseclibs.php'); ...@@ -14,7 +14,6 @@ require_once('xmlseclibs.php');
* @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> * @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
* @package simpleSAMLphp * @package simpleSAMLphp
* @version $Id$ * @version $Id$
* @abstract
*/ */
class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse { class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse {
......
<?php <?php
/**
* This SAML 2.0 endpoint can receive incomming LogoutRequests. It will also send LogoutResponses, and LogoutRequests
* and also receive LogoutResponses. It is implemeting SLO at the SAML 2.0 IdP.
*
* @author Andreas kre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
* @package simpleSAMLphp
* @version $Id$
*/
require_once('../../../www/_include.php'); require_once('../../../www/_include.php');
...@@ -11,23 +19,25 @@ require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php'); ...@@ -11,23 +19,25 @@ require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php');
require_once('SimpleSAML/XML/SAML20/LogoutRequest.php'); require_once('SimpleSAML/XML/SAML20/LogoutRequest.php');
require_once('SimpleSAML/XML/SAML20/LogoutResponse.php'); require_once('SimpleSAML/XML/SAML20/LogoutResponse.php');
require_once('SimpleSAML/Bindings/SAML20/HTTPRedirect.php'); require_once('SimpleSAML/Bindings/SAML20/HTTPRedirect.php');
//require_once('SimpleSAML/Bindings/SAML20/HTTPPost.php');
require_once('SimpleSAML/XHTML/Template.php'); require_once('SimpleSAML/XHTML/Template.php');
$config = SimpleSAML_Configuration::getInstance(); $config = SimpleSAML_Configuration::getInstance();
$metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
$session = SimpleSAML_Session::getInstance();
$idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted'); $idpentityid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
$session = SimpleSAML_Session::getInstance();
$logger = new SimpleSAML_Logger(); $logger = new SimpleSAML_Logger();
$logger->log(LOG_INFO, $session->getTrackID(), 'SAML2.0', 'IdP.SingleLogoutService', 'EVENT', 'Access', $logger->log(LOG_INFO, $session->getTrackID(), 'SAML2.0', 'IdP.SingleLogoutService', 'EVENT', 'Access',
'Accessing SAML 2.0 IdP endpoint SingleLogoutService'); 'Accessing SAML 2.0 IdP endpoint SingleLogoutService');
/*
* If we get an LogoutRequest then we initiate the logout process.
/**
* If we get an incomming LogoutRequest then we initiate the logout process.
* in this case an SAML 2.0 SP is sending an request, which also is referred to as
* SP initiated Single Logout.
*
*/ */
if (isset($_GET['SAMLRequest'])) { if (isset($_GET['SAMLRequest'])) {
...@@ -54,6 +64,7 @@ if (isset($_GET['SAMLRequest'])) { ...@@ -54,6 +64,7 @@ if (isset($_GET['SAMLRequest'])) {
} }
/* Check if we have a valid session. */ /* Check if we have a valid session. */
if($session === NULL) { if($session === NULL) {
/* Invalid session. To prevent the user from being unable to /* Invalid session. To prevent the user from being unable to
* log out from the service provider, we should just return a * log out from the service provider, we should just return a
* LogoutResponse pretending that the logout was successful to * LogoutResponse pretending that the logout was successful to
...@@ -89,8 +100,23 @@ if (isset($_GET['SAMLRequest'])) { ...@@ -89,8 +100,23 @@ if (isset($_GET['SAMLRequest'])) {
error_log('IdP LogoutService: got Logoutrequest from ' . $logoutrequest->getIssuer() . ' '); error_log('IdP LogoutService: got Logoutrequest from ' . $logoutrequest->getIssuer() . ' ');
# $session->setLogoutRequest($logoutrequest);
/*
* Create an assoc array of the request to store in the session cache.
*/
$requestcache = array(
'Issuer' => $logoutrequest->getIssuer(),
'RequestID' => $logoutrequest->getRequestID()
);
if ($relaystate = $logoutrequest->getRelayState() )
$requestcache['RelayState'] = $relaystate;
$session->setLogoutRequest($requestcache);
$session->set_sp_logout_completed($logoutrequest->getIssuer() ); $session->set_sp_logout_completed($logoutrequest->getIssuer() );
$session->setLogoutRequest($logoutrequest);
/* /*
* We receive a Logout Response to a Logout Request that we have issued earlier. * We receive a Logout Response to a Logout Request that we have issued earlier.
...@@ -179,29 +205,40 @@ if ($spentityid) { ...@@ -179,29 +205,40 @@ if ($spentityid) {
error_log('IdP LogoutService: SPs done '); error_log('IdP LogoutService: SPs done ');
try { try {
$logoutrequest = $session->getLogoutRequest(); $requestcache = $session->getLogoutRequest();
if (!$logoutrequest) { if (!$requestcache) {
throw new Exception('Could not get reference to the logout request.'); throw new Exception('Could not get reference to the logout request.');
} }
/**
* Clean up session object to save storage.
*/
if ($config->getValue('debug', false))
$logger->log(LOG_INFO, $session->getTrackID(), 'SAML2.0', 'IdP.SingleLogoutService', 'EVENT', 'SessionSize', 'Size before cleaning: ' . $session->getSize());
$session->clean();
if ($config->getValue('debug', false))
$logger->log(LOG_INFO, $session->getTrackID(), 'SAML2.0', 'IdP.SingleLogoutService', 'EVENT', 'SessionSize', 'Size after cleaning: ' . $session->getSize());
/**
* Create a Logot Response.
*/
$rg = new SimpleSAML_XML_SAML20_LogoutResponse($config, $metadata); $rg = new SimpleSAML_XML_SAML20_LogoutResponse($config, $metadata);
// generate($issuer, $receiver, $inresponseto, $mode ) // generate($issuer, $receiver, $inresponseto, $mode )
$logoutResponseXML = $rg->generate($idpentityid, $requestcache['Issuer'], $requestcache['RequestID'], 'IdP');
$logoutResponseXML = $rg->generate($idpentityid, $logoutrequest->getIssuer(), $logoutrequest->getRequestID(), 'IdP');
// echo '<pre>' . htmlentities($logoutResponseXML) . '</pre>';
// exit();
// Create a HTTP-REDIRECT Binding.
$httpredirect = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata); $httpredirect = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata);
$relayState = SimpleSAML_Utilities::selfURL(); // Find the relaystate if cached.
if (isset($_GET['RelayState'])) { $relayState = isset($requestcache['RelayState']) ? $requestcache['RelayState'] : null;
$relayState = $_GET['RelayState'];
}
//$request, $remoteentityid, $relayState = null, $endpoint = 'SingleLogoutService', $direction = 'SAMLRequest', $mode = 'SP' // Parameters: $request, $remoteentityid, $relayState = null, $endpoint = 'SingleLogoutService', $direction = 'SAMLRequest', $mode = 'SP'
$httpredirect->sendMessage($logoutResponseXML, $idpentityid, $logoutrequest->getIssuer(), $relayState, 'SingleLogoutService', 'SAMLResponse', 'IdP'); $httpredirect->sendMessage($logoutResponseXML, $idpentityid, $requestcache['Issuer'], $relayState, 'SingleLogoutService', 'SAMLResponse', 'IdP');
} catch(Exception $exception) { } catch(Exception $exception) {
...@@ -212,9 +249,6 @@ try { ...@@ -212,9 +249,6 @@ try {
$et->data['e'] = $exception; $et->data['e'] = $exception;
$et->show(); $et->show();
} }
?> ?>
\ No newline at end of file
...@@ -9,7 +9,8 @@ require_once('SimpleSAML/Logger.php'); ...@@ -9,7 +9,8 @@ require_once('SimpleSAML/Logger.php');
require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php'); require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php');
require_once('SimpleSAML/XML/SAML20/LogoutRequest.php'); require_once('SimpleSAML/XML/SAML20/LogoutRequest.php');
require_once('SimpleSAML/XML/SAML20/LogoutResponse.php'); require_once('SimpleSAML/XML/SAML20/LogoutResponse.php');
require_once('SimpleSAML/Bindings/SAML20/HTTPPost.php'); require_once('SimpleSAML/Bindings/SAML20/HTTPRedirect.php');
require_once('SimpleSAML/XHTML/Template.php'); require_once('SimpleSAML/XHTML/Template.php');
$config = SimpleSAML_Configuration::getInstance(); $config = SimpleSAML_Configuration::getInstance();
...@@ -35,11 +36,11 @@ $logger->log(LOG_INFO, $trackId, 'SAML2.0', 'SP.SingleLogoutService', 'EVENT', ' ...@@ -35,11 +36,11 @@ $logger->log(LOG_INFO, $trackId, 'SAML2.0', 'SP.SingleLogoutService', 'EVENT', '
// Destroy local session if exists. // Destroy local session if exists.
if (isset($session) && $session->isAuthenticated() ) { if (isset($session) && $session->isAuthenticated() ) {
$session->setAuthenticated(false); $session->setAuthenticated(false);
$session->clean();
} }
if (isset($_GET['SAMLRequest'])) { if (isset($_GET['SAMLRequest'])) {
// Create a HTTPRedirect binding // Create a HTTPRedirect binding
...@@ -74,7 +75,6 @@ if (isset($_GET['SAMLRequest'])) { ...@@ -74,7 +75,6 @@ if (isset($_GET['SAMLRequest'])) {
} }
$logger->log(LOG_NOTICE, $trackId, 'SAML2.0', 'SP.SingleLogoutService', 'LogoutRequest', $requestid, $logger->log(LOG_NOTICE, $trackId, 'SAML2.0', 'SP.SingleLogoutService', 'LogoutRequest', $requestid,
'IdP (' . $requester . ') is sending logout request to me SP (' . $responder . ')'); 'IdP (' . $requester . ') is sending logout request to me SP (' . $responder . ')');
...@@ -98,6 +98,7 @@ if (isset($_GET['SAMLRequest'])) { ...@@ -98,6 +98,7 @@ if (isset($_GET['SAMLRequest'])) {
// Create a HTTPRedirect binding // Create a HTTPRedirect binding
$binding = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata); $binding = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata);
try { try {
// Decode the LogoutResponse using the HTTP Redirect binding. // Decode the LogoutResponse using the HTTP Redirect binding.
$logoutresponse = $binding->decodeLogoutResponse($_GET); $logoutresponse = $binding->decodeLogoutResponse($_GET);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment