Andreas Korthaus: Problem mit .htaccess und Verzeichnisstruktur

Hallo!

irgendwie werde ich aus den ganzen .htaccess-Sachen immer nur "halbschlau", nie so richtig, auch in der Apache-Doku finde ich meist genau das nicht was ich gerade wissen will.

ich habe folgende Verzeichnisstruktur:

doc-root (öffentlich zugänglich)
    |
    + admin (nur für User aus Gruppe "admin" zugänglich)
    |
    + user (nur für User aus Gruppe "user" zugänglich)

soweit eigentlich ganz einfach, in die beiden Verzeichnisse je eine entsprechende .htaccess und es funktioniert prima.

Das Problem ist, ich habe im doc-root eine html-Datei mit 2 Links:

1. Link ins Verzeichnis "/admin"
2. Link ins Verzeichnis "/user"

Was ich jetzt gerne hätte, ist das wenn eine der Authentifizierungen nicht funktionioniert(401), dass der Anwender auf eine Datei im doc-root geleitet wird, halt in der .htaccess per

ErrorDocument 401 /request.php?error=401

Das Problem daran, die beiden .htaccess liegen im Unterverzeichnis, also müßte das heißen

ErrorDocument 401 ../request.php?error=401

aber das geht nicht, es wird einfach nicht auf besagte Seite geleitet, sondern auf eine Standardseite. Mit einem absoluten Pfad dachte ich könnte es klappen, halt absolut vom Dateisystem aus:

ErrorDocument 401 /www/bla/bla/request.php?error=401

Das geht genausowenig wie die vorherige Variante. Da mit aber im Kopf rumschwebt, das hier das root-Verzsichnis = dem doc-root des Apache sein muß, müßte ja die ursprüngliche Variante

ErrorDocument 401 /request.php?error=401

funktionieren, was aber genauso wenig geht.

Aber da gab es ja noch was mit <Directory>. Ich hatte mir überlegt, nur eine .htaccess in den doc-root zu legen, und hier die verschiedenen Auth-Bereiche mit <Directory> definieren. Das hätte den Vorteil, dass ich

ErrorDocument 401 /request.php?error=401

verwenden könnte. Das habe ich dann so gemacht:

<Directory /admin>
  AuthType Basic
  AuthName "Admin-Login"
  AuthUserFile /www/bla/bla/passwd
  AuthGroupFile /www/bla/bla/groups
  Require group admin
</Directory>

Das ergibt einen 500er Fehler, ohne weitere Angabe in der Error-Log. Dann habe ich noch den absoluten Pfad an Stelle von "/admin" versucht, also "/www/bla/bla/admin" probiert, mit selbem Ergebnis. Ich kann es einfach nicht verstehen. Was mache ich falsch? Das muß doch _beides_ irgendwie gehen, aber wie? Bin dankbar für jeden Tipp oder Link!

Viele Grüße
Andreas

  1. Hallo Andreas,

    ErrorDocument 401 /www/bla/bla/request.php?error=401

    Im Prinzip müsste es so funktionieren (in der .htaccess des Unterverzeichnisses) jedoch scheitert er glaube ich an den URL-Parametern. Für 401er sind nur lokale *PFADE* erlaubt. Mach also einen symbolischen Link (oder eine Kopie unter Windows) auf die request.php und nenne ihn error401.php. Diese Datei muss dann testen, ob sie als request.php oder error401.php aufgerufen worde.

    Ach ja, Deine PHP-Datei muss auf jeden Fall noch den Header ("Status: 401 Authorization required"); mitschicken!

    Grüße,

    Christian

    P.S.: Ich habe im Internet noch eine Diskussion in einer Mailingliste gefunden, an der auch Henryk beteiligt war - da ging es um ein anderes Problem, von dem in der Diskussion jedoch nicht hervorging, ob es inzwischen gelöst ist, oder nicht: https://your.trash.net/pipermail/support/2000-August/000441.html. Vielleicht kann er ja etwas dazu sagen...

    --
    Sollen sich alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen und nicht mehr davon erfasst haben als eine Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst.
                          -- Albert Einstein
    1. Hallo!

      ErrorDocument 401 /www/bla/bla/request.php?error=401

      Im Prinzip müsste es so funktionieren (in der .htaccess des Unterverzeichnisses) jedoch scheitert er glaube ich an den URL-Parametern. Für 401er sind nur lokale *PFADE* erlaubt. Mach also einen symbolischen Link (oder eine Kopie unter Windows) auf die request.php und nenne ihn error401.php. Diese Datei muss dann testen, ob sie als request.php oder error401.php aufgerufen worde.

      Aber wohin kopieren? In dasselbe Verzeichnis wie die .htaccess geht ja nicht, da wird ja _nichts_ ausgeliefert, auch nicht eine 401er Seite.  Das ist ja das doofe :-(
      Und das mit Parametern klappt sonst immer.

      Ach ja, Deine PHP-Datei muss auf jeden Fall noch den Header ("Status: 401 Authorization required"); mitschicken!

      ich mache das ganz ohne PHP. Es ist eine "normale" basic-Authentification, nur die 401er Seite ist PHP, da die einige Aktionen ausführen soll(z.B. "meldung machen " per email...).

      P.S.: Ich habe im Internet noch eine Diskussion in einer Mailingliste gefunden, an der auch Henryk beteiligt war - da ging es um ein anderes Problem, von dem in der Diskussion jedoch nicht hervorging, ob es inzwischen gelöst ist, oder nicht: https://your.trash.net/pipermail/support/2000-August/000441.html. Vielleicht kann er ja etwas dazu sagen...

      Ich weiß auch das ein fast gleiches Problem mal hier im Forum diskutiert worden ist, dieses Jahr, aber meinst Du ich finde das noch? Ich glaube da gab es dann auch eine Lösung!

      Viele Grüße
      Andreas

      1. Hallo Andreas,

        Im Prinzip müsste es so funktionieren (in der .htaccess des Unterverzeichnisses) jedoch scheitert er glaube ich an den URL-Parametern. Für 401er sind nur lokale *PFADE* erlaubt. Mach also einen symbolischen Link (oder eine Kopie unter Windows) auf die request.php und nenne ihn error401.php. Diese Datei muss dann testen, ob sie als request.php oder error401.php aufgerufen worde.
        Aber wohin kopieren? In dasselbe Verzeichnis wie die .htaccess geht ja nicht, da wird ja _nichts_ ausgeliefert, auch nicht eine 401er Seite.  Das ist ja das doofe :-(
        Und das mit Parametern klappt sonst immer.

        Pass auf:

        .htpasswd
        doc-root/
            request.php
            error401.php => request.php
            geschuetztes_verz/
                 .htaccess

        Parameter klappen aber nur, weil ein 302-Redirect erfolgt. Der *darf* aber bei 401 nicht erfolgen. Ergo musst Du den kompletten Pfad auf das Fehlerdokument angeben und kannst _keine_ Paramter übergeben.

        Ach ja, Deine PHP-Datei muss auf jeden Fall noch den Header ("Status: 401 Authorization required"); mitschicken!
        ich mache das ganz ohne PHP. Es ist eine "normale" basic-Authentification, nur die 401er Seite ist PHP, da die einige Aktionen ausführen soll(z.B. "meldung machen " per email...).

        Schon klar - aber PHP sendet Standardmäßig den 200er - auch im Falle eines Fehlerdokuments. Daher musst Du ihn "manuell" korrigieren.

        Grüße,

        Christian

        --
        Sollen sich alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen und nicht mehr davon erfasst haben als eine Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst.
                              -- Albert Einstein
        1. Hallo!

          Und das mit Parametern klappt sonst immer.

          Pass auf:

          .htpasswd
          doc-root/
              request.php
              error401.php => request.php
              geschuetztes_verz/
                   .htaccess

          ich will das bei Aufruf von "www.domain.de/geschuetztes_verz/" das normale basic-auth Fenster aufgeht, halt duch die .htaccess im Verzeichnis. Falls jetzt hier durch den Anwender abgebrochen wird, erzeugt der _Apache_ ja eine 401er Meldung. Mit ErrorDocument kann man der Fehlermeldung halt eine eigene Seite zuweisen, dei dann ausgegeben wird, anstelle von "geschuetztes_verz/". D.h. ich habe im Browser, in dessen Adressleiste tatsächlich "www.domain.de/geschuetztes_verz/" stehen, aber bekomme meine schöne Fehlermeldung, und das muß genau hier noch nichtmal eine PHP-Seite sein, mit einer .html geht es aber genauso wenig. Das ganze hat nichst mit PHP zu tun, geh einfach davon aus ich verwende nur html.

          Parameter klappen aber nur, weil ein 302-Redirect erfolgt.

          Wo erfolgt der? Der Witz ist ja, das das ganze so wie ich es mir überlegtr habe mit "symbolischen" Verzeichnissen klappt, mein provider hat das halt so eingerichtet(keine Ahnung wie das genau geht), dass bei Aufruf von errordocs/ in ein ganz anderes Verzeichnis außerhalb des document roots gelinkt wird. Dahin kann man nicht weiterleiten, da  ein HTTP-Request nunmal nur innerhalb des doc-root gutgehen kann. Der Browser denkt, er sei im geschützen Verzeichnis, bekommt aber eine individuelle Fehlermeldung, die halt in Wirklichkeit außerhalb des doc-root liegt. Und wenn ich mein PHP-Script in dieses Verzeichnis lege und in der .htaccess

          Errordocument 401 errordocs/sript.php?error=401

          angebe, dann funktiomiert e genau so wie ich will, es wird das besagte Script an der eigentlichen login-Adresse angezeigt, welches eine Fehlermeldung und was weiß ich enthält. Das doofe ist nur, das das ganze später auf einen anderen Server soll der das nicht eingerichtet hat, und wo ich hierfür keine Rechte bekomme.

          Der *darf* aber bei 401 nicht erfolgen. Ergo musst Du den kompletten Pfad auf das Fehlerdokument angeben und kannst _keine_ Paramter übergeben.

          Wieso funktioniert es dann? Außerdem habe ich innerhalb des PHP-Scriptes dann gar nicht die Möglichkeit zu prüfen wie die Datei heißt, denn in den Umgebungsvariablen steht tatsächlich das Login-Verzeichnis(www.domain.de/geschuetztes_verz/)! Das ist sehr nützlich für ganz spezielle, punktuelle und individuelle HTTP-Error-Logfiles.... Aber wie gesagt, darum geht es weniger.

          Ach ja, Deine PHP-Datei muss auf jeden Fall noch den Header ("Status: 401 Authorization required"); mitschicken!
          ich mache das ganz ohne PHP. Es ist eine "normale" basic-Authentification, nur die 401er Seite ist PHP, da die einige Aktionen ausführen soll(z.B. "meldung machen " per email...).

          Schon klar - aber PHP sendet Standardmäßig den 200er - auch im Falle eines Fehlerdokuments.

          PHP sendet gar nichts, das ganze wird vom Apachen angestoßen. Geh davon aus dass ich überhaupt kein PHP verwende nur .html.

          Daher musst Du ihn "manuell" korrigieren.

          Das gilt normalerwiese, wenn ich Fehlermeldungen mit PHP erzeuge, aber das mache ich hier nicht(ich wiederhole mich ;-)), der Fehler passiert bei der normalen basic http-authentification. Und da gibte s halt die tollen Errordirektiven die es einem ermöglichen individuell gestaltete Fehlerseiten zu laden, das ist es was ich möchte, und was nicht klappt.

          Viele Grüße
          Andreas

          1. Hallo Andreas,

            ich will das bei Aufruf von "www.domain.de/geschuetztes_verz/" das normale basic-auth Fenster aufgeht, halt duch die .htaccess im Verzeichnis.

            Schon klar.

            Falls jetzt hier durch den Anwender abgebrochen wird, erzeugt der _Apache_ ja eine 401er Meldung.

            Falsch. Diesen Fehler machen alle. Die 401er-Seite wird _immer_ an den Browser gesandt, der zeigt das Fenster an und rednert die Seite *nur dann*, wenn der User auf Abbrechen drückt. Aber es findet bei Abbrechen nur eine einmalige Kommunikation zwischen Server und Client statt.

            [...] geh einfach davon aus ich verwende nur html.

            Ok - werde ich machen.

            Wo erfolgt der? Der Witz ist ja, das das ganze so wie ich es mir überlegtr habe mit "symbolischen" Verzeichnissen klappt, mein provider hat das halt so eingerichtet(keine Ahnung wie das genau geht), dass bei Aufruf von errordocs/ in ein ganz anderes Verzeichnis außerhalb des document roots gelinkt wird. Dahin kann man nicht weiterleiten, da  ein HTTP-Request nunmal nur innerhalb des doc-root gutgehen kann. Der Browser denkt, er sei im geschützen Verzeichnis, bekommt aber eine individuelle Fehlermeldung, die halt in Wirklichkeit außerhalb des doc-root liegt. Und wenn ich mein PHP-Script in dieses Verzeichnis lege und in der .htaccess

            Errordocument 401 errordocs/sript.php?error=401

            Moment - errordocs kann ja nur ein Alias sein - es geht einzig und alleine *darum*, ob die Seite vom Browser aus erreichbar ist. Und wenn das ein Alias ist, dann *ist* die Seite von Browser aus erreichbar, egal ob im Docroot oder nicht. Aber warum das nur klappt, wenn das Ding im errordocs-Unterverzeichnis, das geht über meinen Verstand...

            angebe, dann funktiomiert e genau so wie ich will,
            es wird das besagte Script an der eigentlichen login-Adresse angezeigt, welches eine Fehlermeldung und was weiß ich enthält.

            Hmmmm. Es kommt auch das Fenster, wie? OK, dann klappt das anscheinend auch mit Parametern. (wundert mich)

            Wieso funktioniert es dann?

            Entweder irre ich mich, oder Du begehst einen systematischen Fehler. Such' Dir eines aus. ;)

            Außerdem habe ich innerhalb des PHP-Scriptes dann gar nicht die Möglichkeit zu prüfen wie die Datei heißt, denn in den Umgebungsvariablen steht tatsächlich das Login-Verzeichnis(www.domain.de/geschuetztes_verz/)!

            Dann wird wirklich kein Redirect gemacht... Sicher, dass Du die Paramter bei diesem Test mit angegeben hast?

            PHP sendet gar nichts, das ganze wird vom Apachen angestoßen. Geh davon aus dass ich überhaupt kein PHP verwende nur .html.

            Ok, ich dachte, PHP sendet immer einen Status: 200 - naja.

            Grüße,

            Christian

            --
            Sollen sich alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen und nicht mehr davon erfasst haben als eine Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst.
                                  -- Albert Einstein