Viele Web-Anwendungen verwenden eine eigene Anwendungssession, die in Cookies gespeichert wird, und authentifizieren gegen Shibboleth. Dabei sind sie nicht unbedingt in der Lage, die Session auf Veränderungen zu prüfen, z.B. sie mit einem Remote-User zu assoziieren und so gegen Veränderungen zu schützen. (Siehe dazu auch die Diskussion im Shibboleth-Wiki.)
SLO ist möglich, wenn die Anwendung ein Session-Management verwendet, das robust gegen Manipulationen ist und das Shibboleth-Variablen verwendet. Dann ist die erforderliche Verbindung zwischen Shibboleth-Session und Anwendungs-Session gegeben: Nach dem Logout der Shibboleth-Session ist dann auch die Anwendungssession ungültig und es wird ein erneutes Login an Shibboleth angefordert.
Auf dieser Seite geht es darum, wie man verhindert, dass Nutzer*innen mit einer gültigen Anwendungssession, aber ohne gültige Shibboleth-Authentifizierung eine Webanwendung verwenden:
Dazu wird ein Zusammenhang zwischen Shibboleth-Session und Anwendungssession hergestellt.
Sessions können auf drei verschiedene Arten initialisiert werden:
Die Lösungen variieren je nach Session-Initialisierungsmodus.
Einschränkungen: Es ist nicht möglich, auf einem Server mehrere Anwendungen im Modus „mixedLazy“ und „normal“ bzw. „lazy“ gemeinsam zu betreiben, da bei „mixedLazy“ der sessionHook mit dem zugehörigen Weiterleitungsskript nicht verwendet werden darf (s.u.). Der gemeinsame Betrieb von Anwendungen im Modus „normal“ und „lazy“ stellt kein Problem dar.
Da es nahezu unmöglich ist, alle Bedingungen im Apache-Webserver selbst abzubilden, wird hier auf eine externe Lösung zurückgegriffen: Am Apache-Webserver wird eine RewriteMap konfiguriert, die ein externes Programm aufruft.
Zusätzlich kommt die im Shibboleth-SP verfügbare Technologie des sessionHook zum Einsatz. Damit kann beim Login ein zusätzlicher Request erzeugt werden. Er wird benötigt, um zu erkennen, ob bereits eine Anwendungssession vorhanden ist (Skript s.u.).
Die RewriteMap wird mit Parametern vom Shibboleth-Daemon und vom Webserver aufgerufen. Parameter des Shibboleth-Daemons stehen nicht zu jeder Zeit über Environment-Variablen zur Verfügung. Daher muss die Konfigurationsdirektive ShibUseHeaders on
benutzt werden.
Mögliche Probleme werden unter https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPSpoofChecking erörtert, jedoch wird vom Shibboleth-Daemon ein HeaderSpoofing mit dem Leeren der Shibboleth-Session quittiert, sodass die Gefahr als eher gering eingestuft werden kann. Es wird jedoch dringend empfohlen, in den Shibboleth nachgelagerten Anwendungen auf Environment-Variablen zuzugreifen.
Der Aufruf der RewriteMap mit den erforderlichen Parametern (s.u.) erzeugt vier Rückgabewerte
Mit Hilfe der RewriteMap wird das Prüfskript bei jeder Anfrage an den Webserver ausgeführt. Beim Login beträgt die dadurch zusätzlich verursachte Ausführungszeit bis zu 20 Millisekunden, danach benötigen die Prüfungen i.d.R. unter 0,5 Millisekunden.
Im Session-Initialisierungsmodus „mixedLazy“ sind neben Shibboleth weitere Authentifizierungsmethoden möglich. Bei einer Authentifizierung, die nicht gegen Shibboleth erfolgt, muss man sich auf die Schutzmechanismen der Anwendung verlassen.
Bei Authentifizierungen über Shibboleth können Anmeldungen mit einer bestehenden Session nicht von vornherein unterbunden werden, eine Duplikatsprüfung ist jedoch möglich. Das Prüfskript schaltet danach in den Modus „lazy“. In der Duplikatsprüfung wird untersucht, ob der Identifier der Anwendungssession schon einmal Verwendung fand. Wenn die Bereinigung richtig konfiguriert ist, bietet das quasi den gleichen Schutz wie das Verbot, sich mit einer bestehenden Anwendungssession anzumelden.
Ob eine Anwendungssession besteht, kann und darf hier nicht vorab mittels sessionHook geprüft werden!
Wenn das Prüfskript (s.u.) im Apache-Webserver für die RewriteMap konfiguriert wurde, wird es in der RewriteCond
im zu schützenden Verzeichnis aufgerufen:
RewriteCond ${Context,Shib-Session-ID,Name des Cookies der Anwendungssession,Cookies,[,mixedLazy]} ^return$
Der Aufruf erfolgt mit 4 Parametern und einem optionalen Parameter:
Das Prüfskript führt im ersten Schritt grundsätzliche Validierungen durch:
Zuerst wird geprüft, ob die Shib-Session-ID aus Parameter 2 mit der ermittelten Shib-Session-ID aus dem übertragenen Cookie (Parameter 4) übereinstimmt. Falls nicht, ist die Anfrage ungültig. Dies dient zur Erkennung von Manipulationen am Session-Cookie bzw. an den Headern. Weiterhin wird in diesem Schritt auch geprüft, ob versucht wurde, zusätzliche Anwendungssessions und / oder Cookies mit Shibboleth-Sessions einzuschleusen. Ist dies der Fall, ist die Anfrage ungültig.
Im Context „sessionHook“ wird geprüft, ob keine Anwendungssession vorhanden ist. Bei „normal“ und „lazy“ werden die Anwendungssession und die Shibboleth-Session gegen ein Muster geprüft. Beide Prüfungen müssen erfolgreich sein. Ist diese Prüfung erfolgreich, wird die erweiterte Prüfung durchgeführt.
In der erweiterten Prüfung wird untersucht, ob die Shib-Session-ID im Datenspeicher existiert und ob die dazu passende Anwendungssession-ID geliefert wird. Sind die Anwendungssession-IDs unterschiedlich, ist die Anfrage ungültig. Ist sie gültig, handelt es sich um einen neuen Eintrag, der dann im Datenspeicher vermerkt wird.
Zusätzlich erfolgt bei „mixedLazy“ bei einem Neueintrag die Prüfung, ob die Anwendungssession-ID bereits vergeben wurde. Wenn ja, ist die Anfrage ungültig.
Es existieren noch zwei Sonderzustände:
doLogin
geliefert. Es liegt bei der Administration, auf diesen Zustand mit einer RewriteRule zum Login zu reagieren, falls die Anwendung nicht selbsttätig zum Shibboleth-Login weiterleitet. Achtung: Erfolgt keine Weiterleitung zum Login, so entsteht hier eine Sicherheitslücke, da dann eine ungewollte Anwendungssession eingeschleust werden kann!doAppSession
geliefert. Auf diesen Zustand muss die Administration reagieren, sonst besteht die Gefahr, dass ein Cookie einer vorherigen Session eingeschleust wird! Es muss ein zusätzlicher Request erfolgen, in dem die Anwendungssession in den Variablen für das Prüfskript zur Verfügung gestellt wird. Hierzu bestehen zwei Möglichkeiten:Das Prüfskript ist in PHP geschrieben und verwendet memcached. Es steht unter der GPLv3.
<?php /* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Copyright 2015 Frank Schreiterer, University of Bamberg, Computing Centre */ #unbegrenzt ausführen set_time_limit(0); #set logging to true or false $logging=true; #Pfad zur Logfile $logfile="/var/log/apache2/map.log"; #apt-get install php5-memchache NICHT php5-memchached! $mcsrv="127.0.0.1"; $mcport="11211"; #Lebenzeit der Einträge in Sekunden -> Wert muss an die SessionLifeTime der Shibboleth-Session und der Anwendungs-Session angepasst sein #hier 12 Stunden $mcExpire=43200; #Das Prüfmuster für die Session-ID der Anwendung $regexappsessionid="/^[a-z0-9]{26}$/"; ### Ende User-Konfig ### #es wird versucht, den Overhead für die Verbingung durch die ständige Verbindung zu minimieren, #schlägt bei memcached die Verbindung fehl, so wird die Verbindung selbständig wieder aufgebaut $mc=new Memcache; $mc->connect($mcsrv,$mcport); $keyboard = fopen("php://stdin","r"); $out = fopen("php://stdout","w"); while (1) { #Variablen initialisieren $shibvalid=false; $appvalid=false ; $valid=true; $return=""; $returnmsg=""; $logstr = ""; $mixedlazy = false; $checkappsessionid = false; $appsessionid=""; $shibcookiesessionid=""; $appsessionidmatch=0; $shibcookiesessionidmatch=0; #Ende Variablen initialisieren $input = trim(fgets($keyboard)); $startts = microtime(true); #input zerlegen $tmp = explode(",",$input); #Context -> Parameter 1 bei Aufruf RewriteMap sessionHook wenn über den LoginHook des Shibd aufgerufen wird, lazy für ausschließlich Lazy Session und normal für normale Shib-Session #Der Parameter 5 ist optional und wird verwendet, um dem shibcheker mitzuteilen, dass es sich um die Prüfung im Modus mixedLazy handelt, d. h. die Anwendung unterstützt neben #Shibboleth Lazy Session und ander Authentifizungen. $context = strtolower(trim($tmp[0])); #Shib-Session-ID -> Parameter 2 bei Aufruf RewriteMap $shibsessionid = trim($tmp[1]); #Name der Anwendungssession -> Parameter 3 bei Aufruf RewriteMap $sesscookie = trim($tmp[2]); #die gesetzen Cookies, aus denen der Wert der Anwendungssession extrahiert werden muss -> Parameter 4 bei Aufruf ReweriteMap $cookies = $tmp[3]; #Parameter 5 mixedLazy für Modus mixedLazy, falls die shibsessionid leer ist if (isset($tmp[4]) && strtolower(trim($tmp[4])) == "mixedlazy") { #Prüfung der übermittelten appsessionid auf Duplikate, wenn im Parameter 5 mixedLazy übergeben wurde $checkappsessionid = true; if ($shibsessionid == "") { $mixedlazy = true; } } #aus den Cookies die ID der Anwendungssession extrahieren $regexapp="/^$sesscookie=.*$/"; $regexshib="/^_shibsession_[a-z0-9]+=_[a-z0-9]{32}/"; $tmp = explode(";",$cookies); foreach ($tmp as $cookie) { $cookie = trim($cookie); if (preg_match($regexapp,$cookie)) { $appsessionid = trim(str_replace($sesscookie."=","",$cookie)); $appsessionidmatch++; } if (preg_match($regexshib,$cookie)) { $shibcookiesessionid = trim(preg_replace("/_shibsession_[a-z0-9]+=/","",$cookie)); $shibcookiesessionidmatch++; } } #Es wurde am Shib-Session-Cookie nichts verändert, Veränderung am Cookienamen werden von Shibd mit einer leeren Session-ID im Header quitiert, jedoch #bleibt das Cookie ansich mit der Session-ID bestehen #wird mehr als einmal versucht, ein Cookie mit der Anwendungssession bzw. Shibbolethsession zu übergeben, ist das auch verboten if ($shibsessionid == $shibcookiesessionid && $appsessionidmatch < 2 && $shibcookiesessionidmatch < 2) { #wenn mixedLazy, dann können wir uns alle weiteren Prüfungen sparen, da die Shibboleth-Checks nur ausgeführt werden können, #wenn auch die Anmeldung über Shibboleth erfolgt. #Anderenfalls liegt Die Prüfung der übergebenen Anwendungssession in der Verantwortung der Anwendung und kann hier nicht geprüft werden. if ($mixedlazy == false) { #grundlegende Prüfungen #shibsessionid if (preg_match("/^_[a-z0-9]{32}$/",$shibsessionid)) { $shibvalid=true; } elseif ($shibsessionid != "") { #eine ungültige ID der Shibboleth-Session wurde übermittelt $logstr = "$logstr\nShibboleth-Session-Id $shibsessionid ungültig"; $valid = false; } #appsessionid - hier ggf. Anpassungen vornehmen (ist für PHP-Session) if (preg_match($regexappsessionid,$appsessionid)) { $appvalid=true; } elseif ($appsessionid != "") { #eine ungültige ID der Anwendungs-Session wurde übermittelt $valid = false; $logstr = "$logstr\nAnwendungs-Session-Id $appsessionid ungültig"; } #ist die Anwendungs-Session gesetzt und noch keine Shib-Session gesetzt ist das böse if ($shibvalid == false && $appvalid == true) { $valid = false; $logstr = "$logstr\nAnwendungs-Session-Id $appsessionid vor Shibboleth-Session gesetzt"; } #wurde über den sessionHook aufgerufen, dann darf im Anwendungscookie nichts drin stehen if ($context == "sessionhook" && $appsessionid != "") { $valid = false; $logstr = "$logstr\nAnwendungs-Session-Id $appsessionid im Modus sessionHook gesetzt - verboten"; } #erweiterte Prüfung nur notwendig, wenn nicht abgemeldet werden soll und nicht der sessonHook geprüft wird if ($valid == true && $context != "sessionhook") { #nur weiter prüfen, wenn die Anwendungs-Session und die Shib-Session gültig sind if ($shibvalid == true && $appvalid == true) { #schauen, ob es die Kombination der Sessions schon gibt $item = $mc->get($shibsessionid); #bei memcached-Cluster hier noch aus den anderen lesen und ggf. Werte lokal schreiben if ($item == false) { $logstr = "$logstr\nneue Shibboleth-Session $shibsessionid"; if ($checkappsessionid == true) { #noch prüfen, ob die Anwendungssession nicht schon einmal vergeben wurde, so kann bei mixedLazy die Gefahr minimiert werden, dass versucht wird, mit einer alten Anwendungssession zuzugreifen $get = $mc->get($appsessionid); if ($get != false) { $valid = false; $logstr = "$logstr\nAnwendungs-Session-Id $appsessionid bereits vergeben - ungültig"; } else { $logstr = "$logstr\nPrüfung auf doppelte Anwendungs-Session-Id $appsessionid erfolgreich - Anwendungs-Session-Id $appsessionid nicht vorhanden"; } } #nur weiter, wenn noch gültig if ($valid == true) { #Eintrag in die Sicherungstabelle zur Session schreiben, wenn auch eine Anwendungssession da ist if ($appsessionid != "") { $mc->set($shibsessionid,$appsessionid,false,$mcExpire); $logstr = "$logstr\nSchreibe Key Shibboleth-Session $shibsessionid mit Wert der Anwendungs-Session $appsessionid"; #bei memcached-Cluster hier noch in die weiteren schreiben if ($checkappsessionid == true ) { #und noch die appsessionid als key $mc->set($appsessionid,"$shibsessionid",false,$mcExpire); $logstr = "$logstr\nSchreibe Sicherungseintrag zur Anwendungs-Session $appsessionid"; } } } } elseif ($valid == true) { #prüfen, ob versucht wurde, zur Shibboleth-Session eine andere Kombination mit der Anwendungs-Session unterzuschieben if ($item != $appsessionid) { $valid = false; $logstr = "$logstr\nAnwendungs-Session $appsessionid zur Shibboleth-Session $shibsessionid übermittelt, aber Wert der Anwendungs-Session $item erwartet - ungültig"; } } } #Anwendungs-Session und die Shib-Session gültig else { $valid = false; #SONDERFÄLLE #erster Aufruf bei Lazy-Session if ($shibsessionid == "" && $appsessionid == "" && $context == "lazy") { $returnmsg = "doLogin"; $valid = true; } #dieser Zustand darf bei normaler und bei lazy Session erreicht werden, bei sessionHook kommen wir gar nicht hier hin #es muss zwingend die Anwendungssession initialisiert werden, sonst ist es möglich, eine falsche Session zu verwenden if ($appsessionid == "" && $shibvalid == true) { $valid = true; $returnmsg = "doAppSession"; $logstr = "$logstr\nShibboleth-Session $shibsessionid ohne Anwendungs-Session gefunden - gültig, aber Initialisierung der Anwendungs-Session erforderlich"; } } } #erweiterte Prüfung } # nicht mixedLazy else { $valid = true; $logstr = "$logstr\nModus mixedLazy ohne Shibboleth-Authentifizierung - Anfrage zugelassen"; } } #$shibsessionid == $shibcookiesessionid else { $shibvalid = false; $valid = false; if ($shibsessionid != $shibcookiesessionid) { $logstr = "$logstr\nShibboleth-Session-Id vom Shibd ungleich Shibboleth-Session-Id aus Cookie"; } else { $logstr = "$logstr\nShibboleth- oder Anwendungs-Cookie mehrfach gesetzt"; } } #die Rückgabewerte if ($valid == false) { $return = "doLogout"; } else { $return = "good"; if ($returnmsg != "") { $return = $returnmsg; } } if ($logging == true) { $log = fopen($logfile,"a+"); $now = date("Y-m-d H:i:s"); $nowts = microtime(true); $extime = ($nowts - $startts)*1000; $logstr="\n$now Ausführungsdauer: $extime Millisekunden \nKontext: $context mixedLazy: $mixedlazy shibvalid: $shibvalid appvalid: $appvalid \nEingabe: $input \nshibsessionid: $shibsessionid \nappsessionid: $appsessionid $logstr \nreturn: $return\n"; fwrite($log,$logstr); fclose($log); } fwrite($out,"$return\n"); } ?>
Um die Einträge beim Logout zu entfernen, wird in /etc/shibboleth/shibboleth2.xml
das <Notify>-Element des Shibboleth-Daemons verwendet. Es wird unterhalb des <Session>-Elements definiert und kann für Front- und Back-Channel konfiguriert werden.
Über den Front-Channel werden die Cookies der Anwendung gelöscht. Über den Back-Channel werden die Einträge im Datenspeicher und die Anwendungssession in der Anwendung selbst zerstört.
Konfiguration:
... <Errors supportContact="foobar@beispiel-uni.de" logoLocation="/shibboleth-sp/logo.jpg" styleSheet="/shibboleth-sp/main.css"/> <!-- Here we do the Session removal stuff for both channels--> <Notify Channel="back" Location="https://sp.beispiel-uni.de/PATH/TO/logoutnotify.php" /> <Notify Channel="front" Location="https://sp.beispiel-uni.de/PATH/TO/logoutnotify.php" /> ...
Das Skript logoutnotify.php
wird hier zur Bereinigung aufgerufen:
<?php // Sample PHP 5 Shibboleth logout code by lukas.haemmerle@switch.change_user // History: // - December 8 2008: Uploaded initial version that also was used for Moodle // 2015: Changes for Shibchecker by frank.schreiterer@uni-bamberg.de // Just for debugging the WSDL part ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache /************************************************/ /* Sample code to log out user from application */ /************************************************/ // Requirements: // PHP 5 with SOAP support (should be available in default deployment) // PHP 5 memcache not memcached!!! /* Note: * * It is possible to call the Notify-hook twice in shibboleth2.xml * <Notify Channel="back" Location="URI_TO/logoutnotify.php" /> * <Notify Channel="front" Location="URI_TO/logoutnotify.php" /> * * So we do this and implement on front channel only the destruction for the application cookies an * on back channel the destruction for the application session an the removal of database / memcached - entries * from the shibshecker RewriteMap in our apache configuration. * * The connection parameters to the shibcheckerdb / memcached are set in function LogoutNotification. */ ////////////////////////// // Front channel logout // ////////////////////////// // Note: Generally the back-channel logout should be used once the Shibboleth // Identity Provider supports Single Log Out! // Front-channel logout is not of much use. if ( isset($_GET['return']) && isset($_GET['action']) && $_GET['action'] == 'logout' ){ //Only destroy application cookie via front channel and destroy the application session via back channel // Destroy PHP-session-cookie cookie if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time()-42000, '/'); } // Finally, send user to the return URL header('Location: '.$_GET['return']); exit; } ///////////////////////// // Back channel logout // ///////////////////////// // Note: This is the preferred logout channel because it also allows // administrative logout. However, it requires your application to be // adapated in the sense that the user's Shibboleth session ID must be // stored in the application's session data. // See function LogoutNotification below elseif (!empty(file_get_contents("php://input"))) { // Set SOAP header $server = new SoapServer('https://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'/LogoutNotification.wsdl'); $server->addFunction("LogoutNotification"); $server->handle(); } ///////////////// // Return WSDL // ///////////////// // Note: This is needed for the PHP SoapServer class. // Since I'm not a web service guru it might be that the code below is not // absolutely correct but at least it seems to to its job properly when it // comes to Shibboleth logout else { header('Content-Type: text/xml'); echo <<<WSDL <?xml version ="1.0" encoding ="UTF-8" ?> <definitions name="LogoutNotification" targetNamespace="urn:mace:shibboleth:2.0:sp:notify" xmlns:notify="urn:mace:shibboleth:2.0:sp:notify" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <schema targetNamespace="urn:mace:shibboleth:2.0:sp:notify" xmlns="http://www.w3.org/2000/10/XMLSchema" xmlns:notify="urn:mace:shibboleth:2.0:sp:notify"> <simpleType name="string"> <restriction base="string"> <minLength value="1"/> </restriction> </simpleType> <element name="OK" type="notify:OKType"/> <complexType name="OKType"> <sequence/> </complexType> </schema> </types> <message name="getLogoutNotificationRequest"> <part name="SessionID" type="notify:string" /> </message> <message name="getLogoutNotificationResponse" > <part name="OK"/> </message> <portType name="LogoutNotificationPortType"> <operation name="LogoutNotification"> <input message="getLogoutNotificationRequest"/> <output message="getLogoutNotificationResponse"/> </operation> </portType> <binding name="LogoutNotificationBinding" type="notify:LogoutNotificationPortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="LogoutNotification"> <soap:operation soapAction="urn:xmethods-logout-notification#LogoutNotification"/> </operation> </binding> <service name="LogoutNotificationService"> <port name="LogoutNotificationPort" binding="notify:LogoutNotificationBinding"> <soap:address location="https://{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}"/> </port> </service> </definitions> WSDL; exit; } /******************************************************************************/ /// This function does the actual logout function LogoutNotification($SessionID){ // Delete session of user using $SessionID to locate the user's session file // on the file system or in the database // Then delete this entry or record to clear the session // However, for that to work it is essential that the user's Shibboleth // SessionID is stored in the user session data! //connection parameters to memcached $mcsrv="127.0.0.1"; $mcport="11211"; $mc=new Memcache; $mc->connect($mcsrv,$mcport); //get the application session id $appsessionid = $mc->get($SessionID); //remove $ret = $mc-> delete($SessionID); $ret = $mc-> delete($appsessionid); if ($appsessionid == false) { $appsessionid = ""; } //Connect to the application session (PHP Session) session_id($appsessionid); session_start(); //and destroy $_SESSION = array(); session_destroy(); } ?>
Je nach Anwendungsszenario sind unterschiedliche Konfigurationen notwendig. Für alle Anwendungsszenarien muss die allgemeine Konfiguration durchgeführt werden.
Alle Konfigurationen sind für Apache 2.4. Man beachte, dass sich die Konfigurationselemente von Apache 2.2 nach Apache 2.4 geändert haben, siehe z.B. https://www.switch.ch/aai/support/presentations/techupdate-2014/12_Apache_24_vs_22.pdf, https://www.switch.ch/aai/guides/sp/access-rules/ und https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPApacheConfig.
Alle hier aufgeführten Skripte sind beispielhaft und müssen ggf. angepasst werden.
checker.php
Sorgt für den notwendigen zusätzlichen Request beim SessionHook.
<?php //redirect to application header('Location: '.$_GET['return']); ?>
initsess.php ⇒ Erzeugt eine appsession
<?php //initialize application session session_start(); //applicationpath $path = "Path/to/NORMALAPPLICATION"; //and redirect to application $redirect = "https://".$_SERVER['SERVER_NAME']."/$path"; header('Location: '.$redirect); ?>
remsess.php ⇒ entfernt bei Zugriff mit einer ungültigen Kombination shibsession appsession beides sessions
<?php /* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Copyright 2015 Frank Schreiterer, University of Bamberg, Computing Centre */ function removeMemcached($destid) { $mcsrv="127.0.0.1"; $mcport="11211"; $mc=new Memcache; $mc->connect($mcsrv,$mcport); $stats = $mc->getExtendedStats(); $list = array(); #memcached auslesen und bei passendem Wert den Key entfernen $allSlabs = $mc->getExtendedStats('slabs'); $items = $mc->getExtendedStats('items'); foreach($allSlabs as $server => $slabs) { foreach($slabs AS $slabId => $slabMeta) { if (is_numeric($slabId)) { $cdump = $mc->getExtendedStats('cachedump',(int)$slabId); foreach($cdump AS $keys => $arrVal) { if (!is_array($arrVal)) continue; foreach($arrVal AS $k => $v) { $get = $mc->get($k); if ($get == $destid) { $ret = $mc->delete($k); } } } } } } #und bei mixedLazy den Sicherungseintrag zur destid $ret = $mc->delete($destid); $mc->close(); } #eine böse Anwendungs-Session-ID zerstören if (isset($_REQUEST['appsid'])) { $destid = $_REQUEST['appsid']; if ($destid != "") { session_id($destid); removeMemcached($destid); session_start(); session_destroy(); } } session_start(); $serverurl="https://".$_SERVER['SERVER_NAME']; if (isset($_REQUEST['shibloggedoff'])) { $shiblogoff = $_REQUEST['shibloggedoff']; if ($shiblogoff == "true") { echo "Sie wurden abgemeldet.<br><br>Erneut <a href=\"$serverurl/PATH/TO/Login\">anmelden</a><br>"; } } else { $destid = session_id(); removeMemcached($destid); $url="$serverurl/Shibboleth.sso/Logout?return=$serverurl/PATH/TO/remsess.php?shibloggedoff=true"; header('Location: '.$url); } session_destroy(); #SessionCookie löschen setcookie(session_name(),"",time() -3600,"/"); ?>