[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 // Implements logout for Shibboleth authenticated users according to: 4 // - https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPLogoutInitiator 5 // - https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPNotify 6 7 require_once("../../config.php"); 8 9 require_once($CFG->dirroot."/auth/shibboleth/auth.php"); 10 11 $action = optional_param('action', '', PARAM_ALPHA); 12 $redirect = optional_param('return', '', PARAM_URL); 13 14 // Find out whether host supports https 15 $protocol = 'http://'; 16 if (is_https()) { 17 $protocol = 'https://'; 18 } 19 20 // If the shibboleth plugin is not enable, throw an exception. 21 if (!is_enabled_auth('shibboleth')) { 22 throw new moodle_exception(get_string('pluginnotenabled', 'auth', 'shibboleth')); 23 } 24 25 // Front channel logout. 26 $inputstream = file_get_contents("php://input"); 27 if ($action == 'logout' && !empty($redirect)) { 28 29 if ($USER->auth == 'shibboleth') { 30 // Logout out user from application. 31 require_logout(); 32 // Finally, send user to the return URL. 33 redirect($redirect); 34 } 35 36 } else if (!empty($inputstream)) { 37 38 // Back channel logout. 39 // Set SOAP header. 40 $server = new SoapServer($protocol.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'/LogoutNotification.wsdl'); 41 $server->addFunction("LogoutNotification"); 42 $server->handle(); 43 44 } else { 45 46 // Return WSDL. 47 header('Content-Type: text/xml'); 48 49 echo <<<WSDL 50 <?xml version ="1.0" encoding ="UTF-8" ?> 51 <definitions name="LogoutNotification" 52 targetNamespace="urn:mace:shibboleth:2.0:sp:notify" 53 xmlns:notify="urn:mace:shibboleth:2.0:sp:notify" 54 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 55 xmlns="http://schemas.xmlsoap.org/wsdl/"> 56 57 <!-- 58 This page either has to be called with the GET arguments 'action' and 'return' via 59 a redirect from the Shibboleth Service Provider logout handler (front-channel 60 logout) or via a SOAP request by a Shibboleth Service Provider (back-channel 61 logout). 62 Because neither of these two variants seems to be the case, the WSDL file for 63 the web service is returned. 64 65 For more information see: 66 - https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPLogoutInitiator 67 - https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPNotify 68 --> 69 70 <types> 71 <schema targetNamespace="urn:mace:shibboleth:2.0:sp:notify" 72 xmlns="http://www.w3.org/2000/10/XMLSchema" 73 xmlns:notify="urn:mace:shibboleth:2.0:sp:notify"> 74 75 <simpleType name="string"> 76 <restriction base="string"> 77 <minLength value="1"/> 78 </restriction> 79 </simpleType> 80 81 <element name="OK" type="notify:OKType"/> 82 <complexType name="OKType"> 83 <sequence/> 84 </complexType> 85 86 </schema> 87 </types> 88 89 <message name="getLogoutNotificationRequest"> 90 <part name="SessionID" type="notify:string" /> 91 </message> 92 93 <message name="getLogoutNotificationResponse" > 94 <part name="OK"/> 95 </message> 96 97 <portType name="LogoutNotificationPortType"> 98 <operation name="LogoutNotification"> 99 <input message="getLogoutNotificationRequest"/> 100 <output message="getLogoutNotificationResponse"/> 101 </operation> 102 </portType> 103 104 <binding name="LogoutNotificationBinding" type="notify:LogoutNotificationPortType"> 105 <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> 106 <operation name="LogoutNotification"> 107 <soap:operation soapAction="urn:xmethods-logout-notification#LogoutNotification"/> 108 </operation> 109 </binding> 110 111 <service name="LogoutNotificationService"> 112 <port name="LogoutNotificationPort" binding="notify:LogoutNotificationBinding"> 113 <soap:address location="{$protocol}{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}"/> 114 </port> 115 </service> 116 </definitions> 117 WSDL; 118 exit; 119 } 120 /******************************************************************************/ 121 122 function LogoutNotification($SessionID){ 123 124 global $CFG, $SESSION, $DB; 125 126 // Delete session of user using $SessionID 127 if(empty($CFG->dbsessions)) { 128 129 // File session 130 $dir = $CFG->dataroot .'/sessions'; 131 if (is_dir($dir)) { 132 if ($dh = opendir($dir)) { 133 // Read all session files 134 while (($file = readdir($dh)) !== false) { 135 // Check if it is a file 136 if (is_file($dir.'/'.$file)){ 137 $session_key = preg_replace('/sess_/', '', $file); 138 139 // Read session file data 140 $data = file($dir.'/'.$file); 141 if (isset($data[0])){ 142 $user_session = unserializesession($data[0]); 143 144 // Check if we have found session that shall be deleted 145 if (isset($user_session['SESSION']) && isset($user_session['SESSION']->shibboleth_session_id)){ 146 147 // If there is a match, delete file 148 if ($user_session['SESSION']->shibboleth_session_id == $SessionID){ 149 // Delete session file 150 if (!unlink($dir.'/'.$file)){ 151 return new SoapFault('LogoutError', 'Could not delete Moodle session file.'); 152 } 153 } 154 } 155 } 156 } 157 } 158 closedir($dh); 159 } 160 } 161 } else { 162 // DB Session 163 //TODO: this needs to be rewritten to use new session stuff 164 if (!empty($CFG->sessiontimeout)) { 165 $ADODB_SESS_LIFE = $CFG->sessiontimeout; 166 } 167 168 if ($user_session_data = $DB->get_records_sql('SELECT sesskey, sessdata FROM {sessions2} WHERE expiry > NOW()')) { 169 foreach ($user_session_data as $session_data) { 170 171 // Get user session 172 $user_session = adodb_unserialize( urldecode($session_data->sessdata) ); 173 174 if (isset($user_session['SESSION']) && isset($user_session['SESSION']->shibboleth_session_id)){ 175 176 // If there is a match, delete file 177 if ($user_session['SESSION']->shibboleth_session_id == $SessionID){ 178 // Delete this session entry 179 if (ADODB_Session::destroy($session_data->sesskey) !== true){ 180 return new SoapFault('LogoutError', 'Could not delete Moodle session entry in database.'); 181 } 182 } 183 } 184 } 185 } 186 } 187 188 // If now SoapFault was thrown the function will return OK as the SP assumes 189 190 } 191 192 /*****************************************************************************/ 193 194 // Same function as in adodb, but cannot be used for file session for some reason... 195 function unserializesession($serialized_string) { 196 $variables = array(); 197 $a = preg_split("/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); 198 $counta = count($a); 199 for ($i = 0; $i < $counta; $i = $i+2) { 200 $variables[$a[$i]] = unserialize($a[$i+1]); 201 } 202 return $variables; 203 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |