ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
shib_logout.php
Go to the documentation of this file.
1 <?php
2 
19 require_once("../vendor/composer/vendor/autoload.php");
20 require_once("../artifacts/bootstrap_default.php");
21 
22 global $DIC;
23 $q = $DIC->http()->wrapper()->query();
24 if (
25  $q->has('return')
26  && $q->has('action')
27  && $q->retrieve('action', $DIC->refinery()->to()->string()) === 'logout'
28 ) {
29  entry_point("ILIAS Legacy Initialisation Adapter");
30  // Logout out user from application
31  // Destroy application session/cookie etc
32  $GLOBALS['DIC']['ilAuthSession']->logout();
33 
34  // Finally, send user to the return URL
35  ilUtil::redirect($q->retrieve('action', $DIC->refinery()->kindlyTo()->string()));
36 }
37 
38 // Back channel logout //
39 
40 // Note: This is the preferred logout channel because it also allows
41 // administrative logout. However, it requires your application to be
42 // adapated in the sense that the user's Shibboleth session ID must be
43 // stored in the application's session data.
44 // See function LogoutNotification below
45 
46 elseif (!empty($HTTP_RAW_POST_DATA)) {
48 
49  // Load ILIAS libraries and initialise ILIAS in non-web context
50  entry_point("ILIAS Legacy Initialisation Adapter");
51 
52  // Set SOAP header
53  $server = new SoapServer('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . '/LogoutNotification.wsdl');
54  $server->addFunction("LogoutNotification");
55  $server->handle();
56 }
57 
58 // Return WSDL
59 
60 // Note: This is needed for the PHP SoapServer class.
61 // Since I'm not a web service guru it might be that the code below is not
62 // absolutely correct but at least it seems to to its job properly when it
63 // comes to Shibboleth logout
64 
65 else {
66  header('Content-Type: text/xml');
67 
68  $url = filter_var("https://{$_SERVER['HTTP_HOST']}/shib_logout.php", FILTER_SANITIZE_URL);
69 
70  echo <<<WSDL
71 <?xml version ="1.0" encoding ="UTF-8" ?>
72 <definitions name="LogoutNotification"
73  targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
74  xmlns:notify="urn:mace:shibboleth:2.0:sp:notify"
75  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
76  xmlns="http://schemas.xmlsoap.org/wsdl/">
77 
78  <types>
79  <schema targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
80  xmlns="http://www.w3.org/2000/10/XMLSchema"
81  xmlns:notify="urn:mace:shibboleth:2.0:sp:notify">
82 
83  <simpleType name="string">
84  <restriction base="string">
85  <minLength value="1"/>
86  </restriction>
87  </simpleType>
88 
89  <element name="OK" type="notify:OKType"/>
90  <complexType name="OKType">
91  <sequence/>
92  </complexType>
93 
94  </schema>
95  </types>
96 
97  <message name="getLogoutNotificationRequest">
98  <part name="SessionID" type="notify:string" />
99  </message>
100 
101  <message name="getLogoutNotificationResponse" >
102  <part name="OK"/>
103  </message>
104 
105  <portType name="LogoutNotificationPortType">
106  <operation name="LogoutNotification">
107  <input message="getLogoutNotificationRequest"/>
108  <output message="getLogoutNotificationResponse"/>
109  </operation>
110  </portType>
111 
112  <binding name="LogoutNotificationBinding" type="notify:LogoutNotificationPortType">
113  <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
114  <operation name="LogoutNotification">
115  <soap:operation soapAction="urn:xmethods-logout-notification#LogoutNotification"/>
116  </operation>
117  </binding>
118 
119  <service name="LogoutNotificationService">
120  <port name="LogoutNotificationPort" binding="notify:LogoutNotificationBinding">
121  <soap:address location="{$url}"/>
122  </port>
123  </service>
124 </definitions>
125 WSDL;
126  exit;
127 }
128 
129 /******************************************************************************/
131 function LogoutNotification($SessionID): ?\SoapFault
132 {
133  // Delete session of user using $SessionID to locate the user's session file
134  // on the file system or in the database
135  // Then delete this entry or record to clear the session
136  // However, for that to work it is essential that the user's Shibboleth
137  // SessionID is stored in the user session data!
138 
139  global $ilDB;
140 
141  $q = "SELECT session_id, data FROM usr_session WHERE expires > 'NOW()'";
142  $r = $ilDB->query($q);
143 
144  while ($session_entry = $r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
145  $user_session = unserializesession($session_entry['data']);
146 
147  // Look for session with matching Shibboleth session id
148  // and then delete this ilias session
149  foreach ($user_session as $user_session_entry) {
150  // Delete this session entry
151  if (is_array($user_session_entry) && array_key_exists('shibboleth_session_id', $user_session_entry) && $user_session_entry['shibboleth_session_id'] == $SessionID && !ilSession::_destroy($session_entry['session_id'])
152  ) {
153  return new SoapFault('LogoutError', 'Could not delete session entry in database.');
154  }
155  }
156  }
157  // If no SoapFault is returned, all is fine
158  return null;
159 }
160 
161 /******************************************************************************/
162 // Deserializes session data and returns it in a hash array of arrays
166 function unserializesession($serialized_string): array
167 {
168  $variables = [];
169  $a = preg_split("/(\w+)\|/", (string) $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
170  $counter = count($a);
171  for ($i = 0; $i < $counter; $i += 2) {
172  $variables[$a[$i]] = unserialize($a[$i + 1]);
173  }
174 
175  return ($variables);
176 }
unserializesession($serialized_string)
global $HTTP_RAW_POST_DATA
$url
Definition: shib_logout.php:68
global $DIC
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: shib_logout.php:19
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
$GLOBALS["DIC"]
Definition: wac.php:53
$_SERVER['HTTP_HOST']
Definition: raiseError.php:26
exit
static redirect(string $a_script)
base()
description: > Example for rendering a bulky button.
Definition: base.php:35
static _destroy($a_session_id, ?int $a_closing_context=null, $a_expired_at=null)
Destroy session.
static init(string $a_type)
Init context by type.
$q
Definition: shib_logout.php:23
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
$server
Definition: shib_login.php:28
const CONTEXT_SOAP
header()
expected output: > ILIAS shows the rendered Component.
Definition: header.php:29
entry_point(string $name)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: result1.php:21
$r