Abmeldung über HTTP-Authentifizierung über PHP

Lesezeit: 8 Minuten

Abmeldung uber HTTP Authentifizierung uber PHP
Josef Sabl

Was ist der Korrekt Möglichkeit zum Abmelden vom HTTP-Authentifizierungs-geschützten Ordner?

Es gibt Problemumgehungen, die dies erreichen können, aber sie sind potenziell gefährlich, da sie fehlerhaft sein können oder in bestimmten Situationen / Browsern nicht funktionieren. Deshalb suche ich nach einer korrekten und sauberen Lösung.

  • Bitte geben Sie den Zweck Ihrer Abmeldung an. Soll dies eine erzwungene Abmeldung (Benutzerdeaktivierung) sein? Einfache Logout-Funktion für den Benutzer? Noch etwas?

    – Karsten

    16. Januar 2009 um 9:38 Uhr

  • Ich verstehe nicht, warum das wichtig ist, aber es sind beide Fälle: Deaktivierung aufgrund interner Bedingungen in der Anwendung sowie typischer Abmeldeknopf. Bitte erklären Sie, warum es wichtig ist, ich werde es direkt in die Frage bearbeiten.

    – Josef Sabl

    16. Januar 2009 um 13:02 Uhr

  • Die “richtige und saubere Lösung” wären Browser mit einem eigenen Logout-Button, der, wenn er angeklickt wird, den Browser dazu bringt, die Auth-Header nicht mehr zu senden … Da kann man träumen, oder?

    – DanMan

    21. April 2012 um 17:18 Uhr

  • Die Web Developer Toolbar hat eine solche “Schaltfläche”.

    – Josef Sabl

    23. April 2012 um 7:37 Uhr

  • Was Josef sagte: Webentwickler-Symbolleiste für Firefox -> Miscellaneous -> Clear Private Data -> HTTP Authentication

    – Jarin

    16. Juni 2012 um 22:15 Uhr


Abmeldung uber HTTP Authentifizierung uber PHP
Piskvor verließ das Gebäude

Mu. Es gibt keinen richtigen Wegnicht einmal eine, die über Browser hinweg konsistent ist.

Dies ist ein Problem, das von der kommt HTTP-Spezifikation (Abschnitt 15.6):

Vorhandene HTTP-Clients und Benutzeragenten speichern Authentifizierungsinformationen normalerweise auf unbestimmte Zeit. HTTP/1.1. bietet keine Methode für einen Server, um Clients anzuweisen, diese zwischengespeicherten Anmeldeinformationen zu verwerfen.

Andererseits Abschnitt 10.4.2 sagt:

Wenn die Anfrage bereits Autorisierungsanmeldeinformationen enthielt, zeigt die 401-Antwort an, dass die Autorisierung für diese Anmeldeinformationen verweigert wurde. Wenn die 401-Antwort dieselbe Abfrage wie die vorherige Antwort enthält und der Benutzeragent bereits mindestens einmal versucht hat, sich zu authentifizieren, dann SOLLTE dem Benutzer die Entität präsentiert werden, die in der Antwort angegeben wurde, da diese Entität möglicherweise relevante Diagnoseinformationen enthält.

Mit anderen Worten, Möglicherweise können Sie das Anmeldefeld erneut anzeigen (wie @Karsten sagt), aber der Browser muss Ihre Anfrage nicht berücksichtigen – Verlassen Sie sich also nicht zu sehr auf diese (Fehl-)Funktion.

  • Dies ist ein Fehler im RFC. W3C ist zu faul zum Reparieren. So traurig.

    – Erik Aronesty

    7. Dezember 2012 um 20:14 Uhr

  • Wie @Jonathan Hanson unten vorgeschlagen hat, können Sie ein Tracking-Cookie zusammen mit der HTTP-Authentifizierung verwenden. Das ist für mich die beste Methode.

    – Maschinensüchtig

    11. Juli 2013 um 8:13 Uhr

Abmeldung uber HTTP Authentifizierung uber PHP
Kornel

Methode, die in Safari gut funktioniert. Funktioniert auch in Firefox und Opera, aber mit einer Warnung.

Location: http://[email protected]/

Dies weist den Browser an, die URL mit einem neuen Benutzernamen zu öffnen und den vorherigen zu überschreiben.

  • Gemäß RFC 3986 (URI: Generic Syntax) Abschnitt 3.2.1. (Benutzerinformationen) die Verwendung von user:[email protected] ist veraltet. Nur verwenden http://[email protected]/ ist nicht und sollte in den meisten Fällen funktionieren.

    – aef

    28. April 2011 um 12:55 Uhr


  • @andho: ja, es ist eine Weiterleitung. Sie sollten es mit Status 302 verwenden.

    – Körnel

    6. August 2011 um 11:16 Uhr

  • Anscheinend ein einfacher Link zu [email protected] funktioniert auch (ein “Trennen”-Link zu dieser URL) anstelle einer http-Weiterleitung in PHP … irgendwelche Nachteile?

    – moala

    21. März 2012 um 13:40 Uhr

  • Achtung: Das Senden von Formularen mit relativem Pfad kann fehlschlagen, wenn es nach einer erneuten Anmeldung (Anmeldung mit der Abmeldeaufforderung) erfolgt, da die Adresse immer noch lautet [email protected]/path und nicht yourserver.example.com/path/

    – Jason

    11. April 2012 um 21:55 Uhr


  • [email protected] funktioniert ohne Probleme in Chrome, führt aber zu einer Sicherheitsfrage in Firefox. logout:[email protected] Machen Sie Firefox nicht zu einer Sicherheitsfrage. Keine der beiden URLs funktioniert in IE8 :/

    – Thor A. Pedersen

    26. Juni 2012 um 12:15 Uhr

Die einfache Antwort ist, dass Sie sich nicht zuverlässig von der http-Authentifizierung abmelden können.

Die lange Antwort:
Http-auth (wie der Rest der HTTP-Spezifikation) soll zustandslos sein. „Angemeldet“ oder „abgemeldet“ zu sein, ist also nicht wirklich ein sinnvolles Konzept. Der bessere Weg, dies zu sehen, besteht darin, bei jeder HTTP-Anforderung zu fragen (und denken Sie daran, dass das Laden einer Seite normalerweise aus mehreren Anforderungen besteht): „Dürfen Sie tun, was Sie anfordern?“. Der Server betrachtet jede Anfrage als neu und ohne Bezug zu früheren Anfragen.

Browser haben sich dafür entschieden, sich die Anmeldeinformationen zu merken, die Sie ihnen beim ersten 401 mitteilen, und sie bei nachfolgenden Anfragen ohne die ausdrückliche Erlaubnis des Benutzers erneut zu senden. Dies ist ein Versuch, dem Benutzer das von ihm erwartete “angemeldet/abgemeldet”-Modell zu geben, aber es ist ein reiner Schwindel. Es ist das Browser das simuliert diese Beharrlichkeit des Staates. Der Webserver weiß davon nichts.

Das „Abmelden“ im Kontext von http-auth ist also eine reine Simulation des Browsers und damit außerhalb der Autorität des Servers.

Ja, es gibt Kludges. Aber sie brechen RESTful-ness (wenn das für Sie von Wert ist) und sie sind unzuverlässig.

Wenn Sie für Ihre Site-Authentifizierung unbedingt ein angemeldetes/abgemeldetes Modell benötigen, ist die beste Wahl ein Tracking-Cookie, bei dem die Persistenz des Zustands auf irgendeine Weise auf dem Server gespeichert wird (mysql, sqlite, Flatfile usw.). Dazu müssen alle Anfragen beispielsweise mit PHP ausgewertet werden.

1646637254 515 Abmeldung uber HTTP Authentifizierung uber PHP
Anton Mochalin

Problemumgehung

Sie können dies mit Javascript tun:

<html><head>
<script type="text/javascript">
function logout() {
    var xmlhttp;
    if (window.XMLHttpRequest) {
          xmlhttp = new XMLHttpRequest();
    }
    // code for IE
    else if (window.ActiveXObject) {
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    if (window.ActiveXObject) {
      // IE clear HTTP Authentication
      document.execCommand("ClearAuthenticationCache");
      window.location.href="https://stackoverflow.com/where/to/redirect";
    } else {
        xmlhttp.open("GET", '/path/that/will/return/200/OK', true, "logout", "logout");
        xmlhttp.send("");
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4) {window.location.href="https://stackoverflow.com/where/to/redirect";}
        }


    }


    return false;
}
</script>
</head>
<body>
<a href="#" onclick="logout();">Log out</a>
</body>
</html>

Was oben gemacht wird, ist:

  • für IE – Einfach den Auth-Cache leeren und irgendwo umleiten

  • für andere Browser – Hinter den Kulissen eine XMLHttpRequest mit Login-Name und Passwort zum Abmelden senden. Wir müssen es an einen Pfad senden, der 200 OK auf diese Anfrage zurückgibt (dh es sollte keine HTTP-Authentifizierung erforderlich sein).

Ersetzen "https://stackoverflow.com/where/to/redirect" mit einem Pfad zum Umleiten nach dem Abmelden und Ersetzen '/path/that/will/return/200/OK' mit einem Pfad auf Ihrer Website, der 200 OK zurückgibt.

1646637255 126 Abmeldung uber HTTP Authentifizierung uber PHP
Karsten

Problemumgehung (keine saubere, schöne (oder sogar funktionierende! siehe Kommentare) Lösung):

Deaktivieren Sie seine Anmeldeinformationen einmal.

Sie können Ihre HTTP-Authentifizierungslogik nach PHP verschieben, indem Sie die entsprechenden Header senden (wenn Sie nicht angemeldet sind):

Header('WWW-Authenticate: Basic realm="protected area"');
Header('HTTP/1.0 401 Unauthorized');

Und parsen der Eingabe mit:

$_SERVER['PHP_AUTH_USER'] // httpauth-user
$_SERVER['PHP_AUTH_PW']   // httpauth-password

Das einmalige Deaktivieren seiner Anmeldeinformationen sollte also trivial sein.

  • Das Problem bei dieser Lösung ist Folgendes: Sie lassen IE wissen, dass die Anmeldeinformationen nicht in Ordnung sind. Es zeigt den Anmeldedialog mit leeren Feldern an (es werden keine im Passwortmanager gespeicherten Werte angezeigt). Wenn Sie jedoch auf Abbrechen klicken und die Seite aktualisieren, werden gespeicherte Anmeldeinformationen gesendet, sodass Sie sich erneut anmelden.

    – Josef Sabl

    19. Januar 2009 um 9:38 Uhr

  • Abgestimmt; Wie Josef Sable bemerkte, löst dies das vorliegende Problem nicht.

    – Chris Wesseling

    18. Januar 2012 um 9:31 Uhr


1646637256 617 Abmeldung uber HTTP Authentifizierung uber PHP
Gemeinschaft

Abmeldung von HTTP Basic Auth in zwei Schritten

Nehmen wir an, ich habe einen HTTP Basic Auth-Bereich mit dem Namen „Kennwortgeschützt“ und Bob ist angemeldet. Um mich abzumelden, mache ich 2 AJAX-Anforderungen:

  1. Greifen Sie auf das Skript /logout_step1 zu. Es fügt einen zufälligen temporären Benutzer zu .htusers hinzu und antwortet mit seinem Login und Passwort.
  2. Greifen Sie auf das Skript /logout_step2 zu mit Login und Passwort des temporären Benutzers authentifiziert. Das Skript löscht den temporären Benutzer und fügt diesen Header zur Antwort hinzu: WWW-Authenticate: Basic realm="Password protected"

An diesem Punkt vergaß der Browser Bobs Zugangsdaten.

  • Das Problem bei dieser Lösung ist Folgendes: Sie lassen IE wissen, dass die Anmeldeinformationen nicht in Ordnung sind. Es zeigt den Anmeldedialog mit leeren Feldern an (es werden keine im Passwortmanager gespeicherten Werte angezeigt). Wenn Sie jedoch auf Abbrechen klicken und die Seite aktualisieren, werden gespeicherte Anmeldeinformationen gesendet, sodass Sie sich erneut anmelden.

    – Josef Sabl

    19. Januar 2009 um 9:38 Uhr

  • Abgestimmt; Wie Josef Sable bemerkte, löst dies das vorliegende Problem nicht.

    – Chris Wesseling

    18. Januar 2012 um 9:31 Uhr


Meine Lösung des Problems ist folgende. Sie können die Funktion finden http_digest_parse , $realm und $users im zweiten Beispiel dieser Seite: http://php.net/manual/en/features.http-auth.php.

session_start();

function LogOut() {
  session_destroy();
  session_unset($_SESSION['session_id']);
  session_unset($_SESSION['logged']);

  header("Location: /", TRUE, 301);   
}

function Login(){

  global $realm;

  if (empty($_SESSION['session_id'])) {
    session_regenerate_id();
    $_SESSION['session_id'] = session_id();
  }

  if (!IsAuthenticated()) {  
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Digest realm="'.$realm.
   '",qop="auth",nonce="'.$_SESSION['session_id'].'",opaque="'.md5($realm).'"');
    $_SESSION['logged'] = False;
    die('Access denied.');
  }
  $_SESSION['logged'] = True;  
}

function IsAuthenticated(){
  global $realm;
  global $users;


  if  (empty($_SERVER['PHP_AUTH_DIGEST']))
      return False;

  // check PHP_AUTH_DIGEST
  if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
     !isset($users[$data['username']]))
     return False;// invalid username


  $A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
  $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);

  // Give session id instead of data['nonce']
  $valid_response =   md5($A1.':'.$_SESSION['session_id'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

  if ($data['response'] != $valid_response)
    return False;

  return True;
}

963880cookie-checkAbmeldung über HTTP-Authentifizierung über PHP

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy