Documents:Single Sign Out Moodle

Un article de Wiki ESCO-Portail.

Remarque sur phpCAS et le Single Sing-Out

Pour réaliser le Single Sign-Out au sein de Moodle, l'application phpCAS est utilisée.

Malheureusement, la version de phpCAS > 1.1.2 possède des modifications empêchant le fonctionnement du Single Sign-Out.

C'est pourquoi, actuellement, la version de phpCAS utilisée reste la 1.1.2.

Il pourrait être envisagé de passer sur une version >= 1.2.2, moyennant des modifications.

Ainsi, il faudrait entre autres :

 - Supprimer les appels à des méthodes deprecated;
 - Remanier le code moodle pour répercuter le disparition de certaines variables globales de phpCAS;
 - Appeler les methodes de remplacement aux méthodes deprecated;
 - Appeler les méthodes permettant de conserver le ticket CAS dans l'URL.

Cette liste n'est pas exhaustive.

Détails des modifications effectuées pour le Single Sign-Out dans Moodle

Voir aussi : Fonctionnement du Single Sign-Out avec CAS V.3

Dans login/index.php :

code à insérer après la première ligne (=>require_once("../config.php");<=)

//////////////////////////////////////////////////////////////////////
//                                                                  //
// In login/index.php                                               //
// Manage the logout request sent by CAS                            //
//                                                                  //
//////////////////////////////////////////////////////////////////////
 
// Add from RECIA (T.Bizouerne) for cas Single Sign-Out
 
// Same function as in adodb, but cannot be used for file session for some reason...(taken from auth/shibboleth/logout.php)
function unserializesession( $serialized_string ){
  $variables = array( );
  $a = preg_split( "/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
  for( $i = 0; $i < count( $a ); $i = $i+2 ) {
    $variables[$a[$i]] = unserialize( $a[$i+1] );
  }
  return( $variables );
}
 
// If cas request is detected, terminate the corresponding session
if (isset($_POST) && array_key_exists('logoutRequest', $_POST)) {
  //$logout_request = $_POST['logoutRequest'];
 
  if (isset($_REQUEST['logoutRequest'])) {
    ereg("<samlp:SessionIndex>(ST-[0-9]+-[^<]+)<\/samlp:SessionIndex>" ,$_REQUEST['logoutRequest'] , &$regs);
    error_log("[Moodle] Info : CAS tells that session ".$regs[1]." is ended !");
    $id_ticket_cas_deconnecte = $regs[1];
 
    // Delete session of user using CAS ST
    if(empty($CFG->dbsessions)) {
 
      // File session
      $dir = $CFG->dataroot .'/sessions';
      if (is_dir($dir)) {
	if ($dh = opendir($dir)) {
	  // Read all session files
	  while (($file = readdir($dh)) !== false) {
	    // Check if it is a file
	    if (is_file($dir.'/'.$file)){
	      $session_key = ereg_replace('sess_', '', $file);
	      // Read session file data
	      $data = file($dir.'/'.$file);
	      if (isset($data[0])){
		$user_session = unserializesession($data[0]);
		// Check if we have found session that shall be deleted
		if (isset($user_session['SESSION']) && isset($user_session['SESSION']->ticket)){
		  // If there is a match, delete file
		  if ($user_session['SESSION']->ticket == $id_ticket_cas_deconnecte){
		    // Delete session file
		    if (!unlink($dir.'/'.$file)){
		      error_log("[Moodle] Error : Can't terminate session $id_ticket_cas_deconnecte");
		    }
		    else {
		      error_log("[Moodle] Info : Session $id_ticket_cas_deconnecte successfully terminated");
		    }
		  }
		}
	      }
	    }
	  }
	  closedir($dh);
	}
      }
    }
    else {
      // DB Session
      if (!empty($CFG->sessiontimeout)) {
	$ADODB_SESS_LIFE   = $CFG->sessiontimeout;
      }
 
      if ($user_session_data = get_records_sql('SELECT sesskey, sessdata FROM '. $CFG->prefix .'sessions2 WHERE expiry > NOW()')) {
 
	foreach ($user_session_data as $session_data) {
	  // Get user session
	  $user_session = adodb_unserialize( urldecode($session_data->sessdata) );
	  if (isset($user_session['SESSION']) && isset($user_session['SESSION']->ticket)) {
	    // If there is a match, delete session
	    if ($user_session['SESSION']->ticket == $id_ticket_cas_deconnecte) {
	      // Delete this session entry
	      if (ADODB_Session::destroy($session_data->sesskey) !== true) {
		error_log("[Moodle] Error : Can't terminate session $id_ticket_cas_deconnecte");
	      }
	      else {
		error_log("[Moodle] Info : Session $id_ticket_cas_deconnecte successfully terminated");
	      }
	    }
	  }
	}
      }
    }
  }
 }
// End Add RECIA for Single Sign-Out

Dans auth/cas/auth.php :

Remplacer la fonction user_login par celle-ci.

//////////////////////////////////////////////////////////////////////
//                                                                  //
// In auth/cas/auth.php                                             //
// Store in session the ST id from cas at login                     //
//                                                                  //
//////////////////////////////////////////////////////////////////////
 
function user_login ($username, $password) {
  global $SESSION;
  $this->connectCAS();
  if (phpCAS::isAuthenticated()) {
    if (trim(moodle_strtolower(phpCAS::getUser())) == $username) {
      if (isset($_REQUEST['ticket'])) {
	$SESSION->ticket = $_REQUEST['ticket'];
      }
      else {
	error_log("[Moodle] Error : Can't get ticket ID from CAS - Global Logout will not work");
      }
      return true;
    }
  }
  return false;
}
pages développeurs
pages "communauté ESCO"