Dies ist eine alte Version des Dokuments!


Hilfsscripte

<? php
//redirect to application
header('Location: '.$_GET['return']);
?>
<?php
// Sample PHP 5 Shibboleth logout code by lukas.haemmerle@switch.change_user
// History:
// - December 8 2008:    Uploaded initial version that also was used for Moodle
 
// 2015: Changes for Shibchecker by frank.schreiterer@uni-bamberg.de
 
// Just for debugging the WSDL part
ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache
 
/************************************************/
/* Sample code to log out user from application */
/************************************************/
 
// Requirements:
// PHP 5 with SOAP support (should be available in default deployment)
// PHP 5 memcache not memcached!!!
 
 
 
/* Note:
 * 
 * It is possible to call the Notify-hook twice in shibboleth2.xml 
 * <Notify Channel="back" Location="URI_TO/logoutnotify.php" />
 * <Notify Channel="front" Location="URI_TO/logoutnotify.php" />
 * 
 * So we do this and implement on front channel only the destruction for the application cookies an
 * on back channel the destruction for the application session an the removal of database / memcached - entries 
 * from the shibshecker RewriteMap in our apache configuration.
 * 
 * The connection parameters to the shibcheckerdb / memcached are set in function LogoutNotification.
*/
 
 
//////////////////////////
// Front channel logout //
//////////////////////////
 
// Note: Generally the back-channel logout should be used once the Shibboleth
//       Identity Provider supports Single Log Out!
//       Front-channel logout is not of much use.
 
if (
        isset($_GET['return'])
        && isset($_GET['action'])
        && $_GET['action'] == 'logout'
   ){
 
	//Only destroy application cookie via front channel and destroy the application session via back channel
 
    // Destroy PHP-session-cookie cookie
    if (isset($_COOKIE[session_name()])) {
        setcookie(session_name(), '', time()-42000, '/');
    }
 
    // Finally, send user to the return URL
    header('Location: '.$_GET['return']);    
    exit;
}
 
/////////////////////////
// Back channel logout //
/////////////////////////
 
// Note: This is the preferred logout channel because it also allows
//       administrative logout. However, it requires your application to be
//       adapated in the sense that the user's Shibboleth session ID must be
//       stored in the application's session data.
//       See function LogoutNotification below
 
elseif (!empty($HTTP_RAW_POST_DATA)) {
    // Set SOAP header
    $server = new SoapServer('https://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'/LogoutNotification.wsdl');
    $server->addFunction("LogoutNotification");
    $server->handle();
}
 
/////////////////
// Return WSDL //
/////////////////
 
// Note: This is needed for the PHP SoapServer class.
//       Since I'm not a web service guru it might be that the code below is not
//       absolutely correct but at least it seems to to its job properly when it
//       comes to Shibboleth logout
 
else {
 
    header('Content-Type: text/xml');
 
    echo <<<WSDL
<?xml version ="1.0" encoding ="UTF-8" ?>
<definitions name="LogoutNotification"
  targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
  xmlns:notify="urn:mace:shibboleth:2.0:sp:notify"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns="http://schemas.xmlsoap.org/wsdl/">
 
    <types>
       <schema targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
           xmlns="http://www.w3.org/2000/10/XMLSchema"
           xmlns:notify="urn:mace:shibboleth:2.0:sp:notify">
 
            <simpleType name="string">
                <restriction base="string">
                    <minLength value="1"/>
                </restriction>
            </simpleType>
 
            <element name="OK" type="notify:OKType"/>
            <complexType name="OKType">
                <sequence/>
            </complexType>
 
        </schema>
    </types>
 
    <message name="getLogoutNotificationRequest">
        <part name="SessionID" type="notify:string" />
    </message>
 
    <message name="getLogoutNotificationResponse" >
        <part name="OK"/>
    </message>
 
    <portType name="LogoutNotificationPortType">
        <operation name="LogoutNotification">
            <input message="getLogoutNotificationRequest"/>
            <output message="getLogoutNotificationResponse"/>
        </operation>
    </portType>
 
    <binding name="LogoutNotificationBinding" type="notify:LogoutNotificationPortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="LogoutNotification">
            <soap:operation soapAction="urn:xmethods-logout-notification#LogoutNotification"/>
        </operation>
    </binding>
 
    <service name="LogoutNotificationService">
          <port name="LogoutNotificationPort" binding="notify:LogoutNotificationBinding">
            <soap:address location="https://{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}"/>
          </port>
    </service>
</definitions>
WSDL;
    exit;
 
}
 
/******************************************************************************/
/// This function does the actual logout
function LogoutNotification($SessionID){
 
    // Delete session of user using $SessionID to locate the user's session file
    // on the file system or in the database
    // Then delete this entry or record to clear the session
    // However, for that to work it is essential that the user's Shibboleth
    // SessionID is stored in the user session data!
 
 
	//connection parameters to the shibcheckerdb
	$dbDriver="mysql";
	$dbHost="localhost";
	$dbUser="shibuser";
	$dbPass="Password";
	$dbName="shibchecker";
	$dbPort="3306";
 
	//connection parameters to memcached
	$mcsrv="127.0.0.1";
	$mcport="11211";
 
	//mode memcached or DB
	$mode = "memcached";
	#$mode = "DB";
	
	if ($mode == "DB") {    
		//Remove the entry in shibchecker-DB and the aplication session        
		try {
			$pdo = new PDO("$dbDriver:dbname=$dbName;host=$dbHost;port=$dbPort",$dbUser,$dbPass);
			//get the application session id
			$sqlappsess="Select appsessionid from appshibsession where shibsessionid='$SessionID'";
			$appsessionid = "";
			if ($res = $pdo->query($sqlappsess)) {
				while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
					$appsessionid = $row['appsessionid'];
				}
			}	
			if ($appsessionid != "") {		
				$sql="Delete from appshibsession where appsessionid='$appsessionid'";
				$pdo->query($sql);	
				$pdo = NULL;		
			}				
		} catch (PDOExeption $e) { 
			return new SoapFault('LogoutError', 'Database error.');
		}	
	} elseif ($mode == "memcached") {
		$mc=new Memcache;
		$mc->connect($mcsrv,$mcport);
		//get the application session id
		$appsessionid = $mc->get($SessionID);
		//remove 
		$ret = $mc-> delete($SessionID);
		$ret = $mc-> delete($appsessionid);
		if ($appsessionid == false) {
			$appsessionid = "";
		}
	}
	//Connect to the application session (PHP Session)
	session_id($appsessionid);
	session_start();
	//and destroy
	$_SESSION = array();
	session_destroy();	
}
 
?>
  • Zuletzt geändert: vor 9 Jahren