ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
shib_logout.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 // Just for debugging the WSDL part
5 ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache
6 
15 // Requirements:
16 // PHP 5 with SOAP support (should be available in default deployment)
17 
18 
19 // Front channel logout
20 
21 // Note: Generally the back-channel logout should be used once the Shibboleth
22 // Identity Provider supports Single Log Out!
23 // Front-channel logout is not of much use.
24 
25 if (
26  isset($_GET['return'])
27  && isset($_GET['action'])
28  && $_GET['action'] == 'logout'
29  ){
30 
31  // Load all the IILIAS stuff
32  require_once "include/inc.header.php";
33 
34  global $ilAuth;
35 
36  // Logout out user from application
37  // Destroy application session/cookie etc
38  $ilAuth->logout();
39 
40  // Finally, send user to the return URL
41  ilUtil::redirect($_GET['return']);
42 }
43 
44 // Back channel logout //
45 
46 // Note: This is the preferred logout channel because it also allows
47 // administrative logout. However, it requires your application to be
48 // adapated in the sense that the user's Shibboleth session ID must be
49 // stored in the application's session data.
50 // See function LogoutNotification below
51 
52 elseif (!empty($HTTP_RAW_POST_DATA)) {
53 
54  // Load ILIAS libraries and initialise ILIAS in non-web context
55  require_once("Services/Init/classes/class.ilInitialisation.php");
56  $ilInit = new ilInitialisation();
57  $GLOBALS['ilInit'] =& $ilInit;
58  $ilInit->initILIAS('soap');
59 
60  // Set SOAP header
61  $server = new SoapServer('https://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'/LogoutNotification.wsdl');
62  $server->addFunction("LogoutNotification");
63  $server->handle();
64 }
65 
66 // Return WSDL
67 
68 // Note: This is needed for the PHP SoapServer class.
69 // Since I'm not a web service guru it might be that the code below is not
70 // absolutely correct but at least it seems to to its job properly when it
71 // comes to Shibboleth logout
72 
73 else {
74 
75  header('Content-Type: text/xml');
76 
77  echo <<<WSDL
78 <?xml version ="1.0" encoding ="UTF-8" ?>
79 <definitions name="LogoutNotification"
80  targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
81  xmlns:notify="urn:mace:shibboleth:2.0:sp:notify"
82  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
83  xmlns="http://schemas.xmlsoap.org/wsdl/">
84 
85  <types>
86  <schema targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
87  xmlns="http://www.w3.org/2000/10/XMLSchema"
88  xmlns:notify="urn:mace:shibboleth:2.0:sp:notify">
89 
90  <simpleType name="string">
91  <restriction base="string">
92  <minLength value="1"/>
93  </restriction>
94  </simpleType>
95 
96  <element name="OK" type="notify:OKType"/>
97  <complexType name="OKType">
98  <sequence/>
99  </complexType>
100 
101  </schema>
102  </types>
103 
104  <message name="getLogoutNotificationRequest">
105  <part name="SessionID" type="notify:string" />
106  </message>
107 
108  <message name="getLogoutNotificationResponse" >
109  <part name="OK"/>
110  </message>
111 
112  <portType name="LogoutNotificationPortType">
113  <operation name="LogoutNotification">
114  <input message="getLogoutNotificationRequest"/>
115  <output message="getLogoutNotificationResponse"/>
116  </operation>
117  </portType>
118 
119  <binding name="LogoutNotificationBinding" type="notify:LogoutNotificationPortType">
120  <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
121  <operation name="LogoutNotification">
122  <soap:operation soapAction="urn:xmethods-logout-notification#LogoutNotification"/>
123  </operation>
124  </binding>
125 
126  <service name="LogoutNotificationService">
127  <port name="LogoutNotificationPort" binding="notify:LogoutNotificationBinding">
128  <soap:address location="https://{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}"/>
129  </port>
130  </service>
131 </definitions>
132 WSDL;
133  exit;
134 
135 }
136 
137 /******************************************************************************/
139 function LogoutNotification($SessionID){
140 
141  // Delete session of user using $SessionID to locate the user's session file
142  // on the file system or in the database
143  // Then delete this entry or record to clear the session
144  // However, for that to work it is essential that the user's Shibboleth
145  // SessionID is stored in the user session data!
146 
147  global $ilDB;
148 
149  $q = "SELECT session_id, data FROM usr_session WHERE expires > 'NOW()'";
150  $r = $ilDB->query($q);
151 
152  while($session_entry = $r->fetchRow(DB_FETCHMODE_ASSOC)){
153 
154  $user_session = unserializesession($session_entry['data']);
155 
156  // Look for session with matching Shibboleth session id
157  // and then delete this ilias session
158  foreach($user_session as $user_session_entry){
159  if (
160  is_array($user_session_entry)
161  && array_key_exists('shibboleth_session_id', $user_session_entry)
162  && $user_session_entry['shibboleth_session_id'] == $SessionID){
163 
164  // Delete this session entry
165  if (db_session_destroy($session_entry['session_id']) !== true){
166  return new SoapFault('LogoutError', 'Could not delete session entry in database.');
167  }
168  }
169  }
170  }
171 
172  // If no SoapFault is returned, all is fine
173 }
174 
175 /******************************************************************************/
176 // Deserializes session data and returns it in a hash array of arrays
177 function unserializesession( $serialized_string ){
178  $variables = array( );
179  $a = preg_split( "/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
180  for( $i = 0; $i < count( $a ); $i = $i+2 ) {
181  $variables[$a[$i]] = unserialize( $a[$i+1] );
182  }
183  return( $variables );
184 }
185 
186 ?>