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