5.6 File_HtAccess 

Besprochene Version: 1.1.0 | Lizenz: PHP-Lizenz |
Klassendatei(en): File/HtAccess.php |
Eine weitere Möglichkeit, .htaccess-Dateien zu verarbeiten, bietet das Paket File_HtAccess. Sollten Sie mit .htaccess-Dateien nicht vertraut sein, werfen Sie bitte erst einen Blick auf Abschnitt 5.2.5.
Das Paket stellt eine ideale Ergänzung zum Paket File_Passwd dar, mit dem Sie die .htpasswd-Dateien erstellen können, die Sie benötigen.
Eine typische .htaccess-Datei könnte folgendermaßen aussehen:
AuthName "Interner Bereich" AuthType Basic AuthUserFile /home/netviser/.htpasswd Require valid-user
Am Anfang jeder Zeile steht jeweils eine Direktive, die das Verhalten der Passwortabfrage beeinflusst. Für jede Direktive wird danach ein Wert spezifiziert, der jeweils durch ein Leerzeichen abgetrennt wird.
Das Paket unterstützt zurzeit nur Direktiven, die zur Authentifikation von Benutzern dienen. Somit wird der sonstige Leistungsumfang, den eine .htaccess-Datei abdecken kann, leider nicht unterstützt.
Der oben gezeigte Beispiel-Code sorgt dafür, dass sich eine Passwort-Abfrage öffnet, sobald jemand versucht, auf das Verzeichnis zuzugreifen, in dem die Datei gespeichert ist. Für obiges Beispiel sieht das Fenster so aus:
Abbildung 5.1 Authentifizierungsfenster
Der Wert, der der Direktive AuthName übergeben wurde, wird im Fenster als Überschrift genutzt. Er dient dem Benutzer als Hinweis, wo er sich einloggt. Beim AuthType können Sie theoretisch Basic oder Digest angeben. Hiermit wird definiert, mit welcher Methode die Authentifizierung durchgeführt wird. Digest wäre die bessere Variante, da sie sicherer ist, nur wird sie leider nicht von allen Browsern unterstützt. Somit bleibt Ihnen normalerweise nur der AuthType Basic. AuthUserFile definiert den Pfad und Namen der Datei, in der Benutzernamen und Passwörter hinterlegt sind. In der letzten Zeile, Require valid-user, wird festgelegt, dass jeder User, der in der entsprechenden UserFile-Datei angelegt ist, berechtigt ist, auf das Unterverzeichnis zuzugreifen, wenn er das Passwort korrekt eingibt. Nach der Direktive Require können Sie auch einzelne Benutzernamen angeben, wenn Sie erreichen wollen, dass nur diese Benutzer Zugriff haben. Mit Require user Fry Leela wären nur die Benutzer Fry und Leela zugriffsberechtigt.
Bei der Arbeit mit dieser Klasse müssen Sie unterscheiden, ob es schon eine Datei .htaccess gibt oder nicht. Die Datei .htaccess wird nämlich jedes Mal neu geschrieben, und Sie müssen sich entscheiden, ob Sie die Werte, die schon in der Datei stehen, übernehmen wollen oder alle Werte neu definieren möchten.
require_once('File/HtAccess.php'); // Name der Datei $filename=".htaccess"; // Neues Objekt ableiten $fh = new File_HtAccess($filename); //Existiert die Datei schon? if (true===file_exists($filename)) { // Datei existiert => sie muss eingelesen werden $status=$fh->load(); if (PEAR::isError($status)) { die ("Datei konnte nicht eingelesen werden <br />Grund:".$status->getMessage()); } } else { //Datei existiert noch nicht => komplett neu schreiben. // Default-Direktiven in Array ablegen $params=array ( authname=>"Interner Bereich", authtype=>"Basic", authuserfile=>"/home/.htpasswd" ); // Direktiven an Objekt uebergeben $fh->setProperties($params); } // Require festlegen $fh->setRequire('valid-user'); $status=$fh->save(); if (PEAR::isError($status)) { die ("Konnte Datei nicht schreiben<br /> Grund:"$status->getMessage()); }
Listing 5.6 Verarbeiten einer .htaccess-Datei
Der Konstruktor der Klasse bekommt den Namen der Datei, mit der gearbeitet werden soll, als Parameter übergeben. Da der Name nicht unbedingt .htaccess sein muss, ist es durchaus sinnvoll, ihn variabel zu halten. Mit Hilfe der nachfolgenden if-Abfrage wird geprüft, ob es in diesem Verzeichnis schon eine entsprechende Datei gibt. Gibt es sie, wird sie geladen. Die dort enthaltenen Direktiven und Werte werden komplett ausgelesen und im Objekt abgelegt. Sollte der Ladevorgang fehlschlagen, liefert die Methode ein PEAR_Error-Objekt zurück, was danach geprüft wird.
Ist die Datei noch nicht vorhanden, kommt die Methode setProperties() zum Einsatz. Ihr wird ein Array übergeben, das die wichtigsten Direktiven enthält, um eine funktionsfähige .htaccess-Datei zu generieren. Im Schlüssel 'authname' wird der Name des zu schützenden Bereichs abgelegt, wobei zu beachten ist, dass ein Name, der aus mehreren Wörtern besteht, problematisch sein kann. Um mehrere Wörter zu nutzen, sollten Sie den Namen entweder mit entwerteten Anführungszeichen (\") einschließen oder die einzelnen Wörter mit einem Unterstrich verbinden. Der Key 'authtype' bekommt Wert 'Basic' übergeben, und das letzte Element 'authuserfile' beinhaltet den Namen und Pfad der Passwortdatei. Wichtig dabei ist, dass hier ein absoluter Pfad anzugeben ist.
Die Methode setProperties() können Sie auch nutzen, um die Direktiven in einer bestehenden Datei zu überschreiben. Dabei ist es nicht notwendig, alle Direktiven in dem Array anzugeben. Es reicht aus, die Werte zu nennen, die Sie manipulieren wollen. Leider ist momentan keine Möglichkeit implementiert, bereits definierte Werte auszulesen.
Um zu definieren, welche Benutzer Zugriff haben, können Sie die Methode setRequire() nutzen. Die Methode bekommt entweder den String 'valid–user' oder ein Array mit Benutzernamen übergeben. Die erste Variante würde dazu führen, dass jeder Benutzer, der in der Passwort-Datei definiert ist, auch Zugriff hat. Übergeben Sie der Methode ein Array, so können Sie einzelne Benutzer spezifizieren, die Zugriff haben sollen. Der erste Eintrag im Array muss dabei der String 'user' sein. Mit der Ergänzung
hätten nur die User Fry und Leela Zugriff auf die geschützten Daten. setRequire() definiert die Zugriffsrechte neu, das heißt, eine bestehende Rechtevergabe wird überschrieben.
Bevorzugen Sie eine gruppenbasierende Authentifikation, übergeben Sie in dem Array als ersten Parameter nicht 'user', sondern 'group'. Danach folgen in dem Array die Namen der berechtigten Gruppen. In diesem Fall muss allerdings in dem Array, das an setParams() übergeben wird, mithilfe der Direktive 'authgroupfile' ein Pfad und Name der Datei spezifiziert werden, in der die Gruppendefinitionen abgelegt sind.
Nachdem Sie alle notwendigen Änderungen an das Objekt übergeben haben, rufen Sie einfach die Methode save() auf, um die Datei zu speichern. Die Datei wird überschrieben, wenn sie bereits existiert. Existiert sie noch nicht, wird sie neu angelegt. Sollte das Speichern fehlschlagen, was die letzte if-Abfrage testet, prüfen Sie bitte, ob der User, unter dem der Webserver ausgeführt wird, Schreibrechte auf die entsprechende Datei und das Unterverzeichnis hat.
Die Methode getRequire() liest aus einer bestehenden .htaccess-Datei aus, welche Benutzer Zugriff haben, und liefert Ihnen ein Array zurück.
require_once('File/HtAccess.php'); $filename=".htaccess"; $fh = new File_HtAccess($filename); if (true===file_exists($filename)) { $fh->load(); $user=$fh->getRequire(); echo ("Die Benutzerrechte lauten: "); echo (implode($user," ")); } else { echo ("Die Datei $filename existiert nicht"); }
Auf dem Bildschirm erscheint dann beispielsweise
Die Benutzerrechte lauten: valid-user
Im ersten Array-Element ist also entweder 'valid-user' oder 'user' enthalten, wenn Sie eine benutzerabhängige Authentifikation vornehmen. Bei einer gruppenbasierenden Absicherung ist dementsprechend 'group' enthalten.
Mit den Methoden delRequire() und addRequire() können Sie jeweils einzelne Benutzer aus der Liste entfernen oder hinzufügen. Beide Methoden werden nach dem Laden der Datei aufgerufen und bekommen einen Benutzernamen als Parameter übergeben. Somit wird mit
der Benutzer Fry entfernt und mit
der User Leela zur Liste der User hinzugefügt. Leider sind die Funktionen nicht wirklich intelligent. Wenn Sie bereits 'valid-user' nutzen und mit Hilfe von addRequire() den User NewUser hinzufügen, so würde daraus diese Direktive resultieren:
Require valid-user NewUser
Die Funktionen machen also einfach das, was sie tun sollen, ohne zu überprüfen, ob es logisch korrekt ist. Im Zweifelsfall sollten Sie also mit setRequire() die Daten komplett neu schreiben und sie nicht nur verändern.