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