Clemens Gruber: Verzeichnisschutz .htaccess ohne Pop-Up / apache_lookup_uri()

Beitrag lesen

Ich möchte .htaccess/.htpasswd zum Verzeichnisschutz verwenden. Allerdings soll zur Authentifizierung nicht das obligatorische Pop-Up zum Einsatz kommen, sondern aus CI-Gründen ein Formular, das sich "netter" in die Webseite integrieren lässt. Hier gibt es allerdings Probleme. Aber zunächst folgendes:

1. Warum .htaccess/.htpasswd?
Das Problem bei anderen Authentifizierungsmöglichkeiten z.B. über PHP- oder Perl-Skripts ist, dass hier vor jedem Skript/jeder Datei das Authentifizierungs-Script aufgerufen werden muss. Teilweise - z.B. bei reinen "PHP-Kulturen" geht das mit einem Eintrag in der .htaccess die bspw. die Zeile php_auto_prepend_file authentifizierung.php enthält. Bei "Mischkulturen," also  PHP und HTML, sHTML usf., geht das schon wieder nicht mehr; und bei "exotischen" Dateien wie PDF, doc, Binarys oder auch bei Grafiken geht das - meines Wissens, ich lasse mich da aber gerne korrigieren - überhaupt nicht. Ist - aus welchen Gründen auch immer - die URL (z.B. www.domain.de/geschuetzt/geschaeftsbericht.pdf) bekannt, hat jeder und jede Zugriff auf die entsprechende Datei.

2. Login und Passwort über ein Formular eingeben
Man kann nun wie im Beispiel unten eine URL der Form  http://login:passwort@www.domain.de/geschuetzt/
erzeugen und sich so mit einem eigenen Formular mit dem bestehenden .htaccess/.htpasswd-Schutz einzuloggen.

<html>
<head>
  <script language="JavaScript1.2">
    <!--
      function einloggen()
      {
        var url="http://" +document.input['login'].value+ ":"
            +document.input['passwort'].value+
            "@www.domain.de/geschuetzt/";
        self.location=url;
      }
    // -->
</script>
</head>

<body>
  <form name=input>
    Login:    <input name=login type=text size=10 maxlength=10>
    Passwort: <input name=passwort type=password size=10 maxlength=10>
    <input type=button value="OK" onClick="einloggen()">
  </form>
</body>
</html>

Das geht bei richtigem Login/Passwort ohne Probleme. Allerdings sieht es bei Falschangeben schlecht aus. Hier kommt wieder das Pop-Up und die Apache-seitige Error-Meldung 403. Scheinbar ist das Pop-Up auch nicht zu unterdrücken, in einem Posting (http://213.139.94.131/selfhtml/sfarchiv/2000_2/t13744.htm) hieß es: "Soweit ich weiß, tritt der 403-Fehler erst dann auf, wenn der Browser seinen lokalen retry-Dialog erfolglos beendet hat. Das aber ist eine Eigenschaft des Browsers und durch Serverkonfiguration nicht zu beeinflussen."

3. Anklopfen mit apache_lookup_uri($name)
Meine Idee war nun nicht direkt http://login:passwort@www.domain.de/geschuetzt/ die URL aufzurufen, sondern erst einmal "anzuklopfen" und bei entsprechendem "Alles richtig, herein!" die URL zu übergeben.

Unter PHP gibt es spezifische Funktionen für den Apache Webserver, u.a. die Funktion
apache_lookup_uri($name) mit $name = Name der URI, die ein Objekt (!) mit Elementen über die angegebene Quelle (URI) erzeugt, u.a. auch den Status des HTTP-Response bei Aufruf der angegebenen URI, dabei ist der Status das erste Element des Objekts.

Wenn man mit apache_lookup_uri("www.domain.de/geschuetzt ") den Status ausliest bekommt man also 401, und bei apache_lookup_uri("www.domain.de/_nicht_geschuetzt ")
200 zurück geliefert.

Nun war meine Idee, man könnte das auch mit login:passwort@www.domain.de/geschuetzt/
machen. Wird dann bei richtiger Passwort/Login-Kombination 200 als Status zurückgeliefert kann man auf die entsprechende Seite weiterleiten. Wenn nicht, wird einfach nochmals das Formular etwa mit der Bemerkung "Falsche Eingabe. Bitte noch einmal versuchen!" aufgerufen.

Aber es funktioniert nicht. Unten habe ich alle Elemente des mit apache_lookup_uri("test:test@stuff/test/index.html"); erzeugten Objekts ausgegeben. Scheinbar wird Login und Passwort einfach nicht richtig aufgelöst, sondern einmal anscheinend als Teil des Path interpretiert (unten bei URI), oder nur der Teil test:test@stuff (bei Filename) oder der Teil nach @stuff (bei path_info). Auch der Status ist falsch, de mit Login: test und PW: test kein Zugang möglich ist.

status => 200
the_request => GET /test HTTP/1.0
method => GET
uri => /test:test@stuff/test/index.html
filename => /[...]/www.[domain].de/test:test@stuff
path_info => /test/index.html
no_cache => 0
no_local_copy => 1
allowed => 0
sent_bodyct => 0
bytes_sent => 0
byterange => 0
clength => 0
unparsed_uri => /test:test@stuff/test/index.html
mtime => 990574711
request_time => 990576082

Ich habe das auch mit anderen Pfadangeben versucht:
apache_lookup_uri("test:test@/stuff/test/index.html");
apache_lookup_uri("test:test@http://www.[domain].de/stuff/test/index.html")
apache_lookup_uri("test:test@www.[domain].de/stuff/test/index.html")
apache_lookup_uri("test:test@/...pfad.../www.[domain].de/stuff/test/index.html")
apache_lookup_uri("test:test@...pfad.../www.[domain].de/stuff/test/index.html")

aber auch das war nichts!

Nur noch zur Information: das Skript lookup.php
...
$cl= apache_lookup_uri("test:test@stuff/test/index.html");
foreach ($cl as $k=>$elem) {echo "$k => $elem<br>";}
...
steht im root-Verzeichnis (www.[domain].de/lookup.php) das zu schützende Verzeichnis ist
www.[domain].de/stuff/test/

Fragen
Hat jemand eine Idee, wie man mit apache_lookup_uri() doch noch Login und Passwort einbauen kann?
Ist überhaupt die Überprüfung der Login-Daten bei der apache_lookup_uri()-Funktion theoretisch möglich?
Nach welchen Regeln wird die URI aufgelöst und was geschieht mit test:test@?
Gibt es so etwas auch bei Perl oder mit SSI-Syntax?
In welcher Reihenfolge läuft bei http://login:passwort@www.domain.de/geschuetzt/ die Authentifizierung und Überprüfung der Daten ab?