ILIAS  release_4-3 Revision
 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  include_once "Services/Context/classes/class.ilContext.php";
56 
57  // Load ILIAS libraries and initialise ILIAS in non-web context
58  require_once("Services/Init/classes/class.ilInitialisation.php");
60 
61  // Set SOAP header
62  $server = new SoapServer('https://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'/LogoutNotification.wsdl');
63  $server->addFunction("LogoutNotification");
64  $server->handle();
65 }
66 
67 // Return WSDL
68 
69 // Note: This is needed for the PHP SoapServer class.
70 // Since I'm not a web service guru it might be that the code below is not
71 // absolutely correct but at least it seems to to its job properly when it
72 // comes to Shibboleth logout
73 
74 else {
75 
76  header('Content-Type: text/xml');
77 
78  echo <<<WSDL
79 <?xml version ="1.0" encoding ="UTF-8" ?>
80 <definitions name="LogoutNotification"
81  targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
82  xmlns:notify="urn:mace:shibboleth:2.0:sp:notify"
83  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
84  xmlns="http://schemas.xmlsoap.org/wsdl/">
85 
86  <types>
87  <schema targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
88  xmlns="http://www.w3.org/2000/10/XMLSchema"
89  xmlns:notify="urn:mace:shibboleth:2.0:sp:notify">
90 
91  <simpleType name="string">
92  <restriction base="string">
93  <minLength value="1"/>
94  </restriction>
95  </simpleType>
96 
97  <element name="OK" type="notify:OKType"/>
98  <complexType name="OKType">
99  <sequence/>
100  </complexType>
101 
102  </schema>
103  </types>
104 
105  <message name="getLogoutNotificationRequest">
106  <part name="SessionID" type="notify:string" />
107  </message>
108 
109  <message name="getLogoutNotificationResponse" >
110  <part name="OK"/>
111  </message>
112 
113  <portType name="LogoutNotificationPortType">
114  <operation name="LogoutNotification">
115  <input message="getLogoutNotificationRequest"/>
116  <output message="getLogoutNotificationResponse"/>
117  </operation>
118  </portType>
119 
120  <binding name="LogoutNotificationBinding" type="notify:LogoutNotificationPortType">
121  <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
122  <operation name="LogoutNotification">
123  <soap:operation soapAction="urn:xmethods-logout-notification#LogoutNotification"/>
124  </operation>
125  </binding>
126 
127  <service name="LogoutNotificationService">
128  <port name="LogoutNotificationPort" binding="notify:LogoutNotificationBinding">
129  <soap:address location="https://{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}"/>
130  </port>
131  </service>
132 </definitions>
133 WSDL;
134  exit;
135 
136 }
137 
138 /******************************************************************************/
140 function LogoutNotification($SessionID){
141 
142  // Delete session of user using $SessionID to locate the user's session file
143  // on the file system or in the database
144  // Then delete this entry or record to clear the session
145  // However, for that to work it is essential that the user's Shibboleth
146  // SessionID is stored in the user session data!
147 
148  global $ilDB;
149 
150  $q = "SELECT session_id, data FROM usr_session WHERE expires > 'NOW()'";
151  $r = $ilDB->query($q);
152 
153  while($session_entry = $r->fetchRow(DB_FETCHMODE_ASSOC)){
154 
155  $user_session = unserializesession($session_entry['data']);
156 
157  // Look for session with matching Shibboleth session id
158  // and then delete this ilias session
159  foreach($user_session as $user_session_entry){
160  if (
161  is_array($user_session_entry)
162  && array_key_exists('shibboleth_session_id', $user_session_entry)
163  && $user_session_entry['shibboleth_session_id'] == $SessionID){
164 
165  // Delete this session entry
166  if (ilSession::_destroy($session_entry['session_id']) !== true){
167  return new SoapFault('LogoutError', 'Could not delete session entry in database.');
168  }
169  }
170  }
171  }
172 
173  // If no SoapFault is returned, all is fine
174 }
175 
176 /******************************************************************************/
177 // Deserializes session data and returns it in a hash array of arrays
178 function unserializesession( $serialized_string ){
179  $variables = array( );
180  $a = preg_split( "/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
181  for( $i = 0; $i < count( $a ); $i = $i+2 ) {
182  $variables[$a[$i]] = unserialize( $a[$i+1] );
183  }
184  return( $variables );
185 }
186 
187 ?>