Sonja: Komplette Seite bis auf einige Dateien mit .htaccess schützen

Hallo zusammen,

mein Projekt befindet sich im Beta-Stadium und ist für breites Publikum momentan nicht zugänglich. Das bedeutet, dass ich die komplette Seite mit einem Passwort versehen möchte. Aber! Beim Aufruf meiner URL, soll nicht gleich einer htaccess-Passwortabfrage kommen, sondern einer Startseite mit Begrüßung und darunter ein Link über den der Beta-Tester .htaccess aktiv "aufrufen" kann.

Da die Inhalte direkt im root-Verzeichnis liegen, muss ich auch root-Verzeichnis schützen. Kann ich den hier einige Dateien (Startseite, css etc.) vom Passwortschutz ausschließen?

Verschieben von allen Inhalten in einen geschützten Unterordner kommt nicht in Frage. Idealerweise sollte nach dem Entfernen vom Passwortschutz alles sofort funktionieren.

Tja, viel geschrieben :) Zusammengefasst: wie schütze ich die komplette Seite mit Ausnahme von ein paar Dateien (nicht Verzeichnissen!) mit .htaccess? Geht es?

Danke,
Sonja

  1. [W]ie schütze ich die komplette Seite mit Ausnahme von ein paar Dateien (nicht Verzeichnissen!) mit .htaccess? Geht es?

    Ja - aber da .htaccess über keine derartige Logik verfügt, wirst Du alle Dateien einzeln eintragen müssen, solange sie nicht gesammelt in einem Unterverzeichnis sind.

    Gruß, LX

    --
    X-Self-Code: sh:( fo:) ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: Unusual
    X-Please-Search-Archive-First: Absolutely Yes
    1. Halo LX,

      Ja - aber da .htaccess über keine derartige Logik verfügt, wirst Du alle Dateien einzeln eintragen müssen, solange sie nicht gesammelt in einem Unterverzeichnis sind.

      Danke für Deine schnelle Antwort. Dass ich die "erlaubten" Dateien manuell eintragen muss, ist mir bewusst. Zugestehen mit einem Halbwissen aufgebaute .htaccess funktioniert nicht.

      ErrorDocument 401 /betatest.html
      ErrorDocument 404 /notfound.html

      AuthName "BetaTest"
      AuthType Basic
      AuthUserFile /home/www/.htpasswd
      require valid-user

      <FilesMatch "(betatest.html|styles.css|logo.jpg)$">
      Allow from All
      </FilesMatch>

      Beim Aufruf der Seite kommt sofort die .htaccess Abfrage. Ich möchte aber, dass erst betatest.html angezeigt wird und erst über einen Link die Passwortabfrage kommt. Irgenwie komme ich hier nicht weiter.

      Für jeden Tip bin ich dankbar.

      Gruß,
      Sonja

      1. Hi Sonja,

        Beim Aufruf der Seite kommt sofort die .htaccess Abfrage. Ich möchte aber, dass erst betatest.html angezeigt wird und erst über einen Link die Passwortabfrage kommt. Irgenwie komme ich hier nicht weiter.

        wo liegt das Problem? In Dein oberstes Verzeichnis Deiner Dokumente gibst Du eine index.html oder eine index.php, die jeder ohne Passwort ganz normal abrufen kann.

        Dann legst Du (in diesem Verzeichnis) einen neuen Ordner an, in den die geschützeten Seiten und eine .htaccess-Datei kommen. Von der index-Seite dann Links zu Ressourcen im geschützten Verzeichnis zu legen, wird ja kein Problem sein.

        Mit lieben Grüßen

        Onkel Hans

        1. Hallo Onkel Hans,

          wo liegt das Problem? In Dein oberstes Verzeichnis Deiner Dokumente gibst Du eine index.html oder eine index.php, die jeder ohne Passwort ganz normal abrufen kann. Dann legst Du (in diesem Verzeichnis) einen neuen Ordner an, in den die geschützeten Seiten und eine .htaccess-Datei kommen.

          Genau daran liegt mein Problem, dass ich keine geschützte Verzeichnisse benötige, sondern _die ganze Seite_ mit Passwort schützen möchte. Allerdings möchte ich auch, dass beim Aufruf der URL nicht sofort die Passwortabfrage erscheint, sondern erst eine Startseite angezeigt wird. Diese einzige Seite soll _nicht_ passwortgeschützt sein und erst beim Klick auf "Beta-Test"-Link eine Passwortabfrage kommen. Mehr nicht.

          Ich möchte nicht das gesamte Projekt für die Dauer des Tests in ein Unterverzeichnis schieben. Wie ich oben geschrieben habe, idealerweise sollte irgendwann nach dem Entfernen/Bearbeiten von .htaccess die ganze Seite (ohne Verschieben der Inhalte und Quelltextänderungen) erreichbar sein.

          Ein halb funktionierendes Beispiel:

          ErrorDocument 401 /betatest.html
          ErrorDocument 403 /betatest.html
          ErrorDocument 404 /error404.html

          <Files *>
          Order allow,deny
          Allow from all
          AuthName "Betatest"
          AuthType Basic
          AuthUserFile /home/www/xxxxxxxxxxxxxxxxxx/.htpasswd
          require valid-user
          </Files>

          <FilesMatch "(betatest.html|styles.css|logo.jpg|error404.html)$">
          Allow from All
          Satisfy any
          </FilesMatch>

          Was hier nicht klappt. Beim Aufruf der URL wird eine Passwortabfrage gestartet. Gewünscht ist aber, dass die Seite betatest.html ohne Passwortabfrage angezeigt wird. Alle anderen Dateien, die nicht explizit in
           FilesMatch-Direktive angegeben sind, sollten geschützt sein. Und genaue hier komme ich nicht weiter.

          Gruß,
          Sonya

      2. Hi,

        <FilesMatch "(betatest.html|styles.css|logo.jpg)$">
        Allow from All
        </FilesMatch>

        Siehe diesen aktuellen Thread zum gleichen Thema - da muesste ein Satisfy Any hin.

        MfG ChrisB

        --
        „This is the author's opinion, not necessarily that of Starbucks.“
        1. Hallo ChrisB,

          <FilesMatch "(betatest.html|styles.css|logo.jpg)$">
          Allow from All
          </FilesMatch>

          Siehe diesen aktuellen Thread zum gleichen Thema - da muesste ein Satisfy Any hin.

          Jup, habe ich gemacht. Irgendwie drehe ich mich aber bei dem Problem "Wie sage ich dem Server, dass er betatest.html anzeigen soll, wenn User nicht berechtigt ist und nicht sofort mit der Passwortabfrage starten soll?".

          Um es ganz genau zu machen. Mein Projekt hat DirectoryIndex index.php. Die index.php und alle Dateien, die ich nicht explizit in FilesMatch-Direktive erlaube, sollen geschützt sein. Wenn meine Url ohne explizite Angabe einer Seite aufgerufen wird, dann versucht der Server index.php aufzurufen und fragt nach dem Passwort.

          Im Grunde genommen möchte ich den Zugriff auf index.php nur erlauben, wenn Benutzer berechtigt ist, und gleichzeitig aber die Passwortabfrage für index.php (nur diese Datei) unterbinden - bin ich nicht kompliziert? ;)

          OK, der nächste Ansatz wäre mod_rewrite für Zugriff auf / bzw. index.php mit Header 401/403 und Weiterleitung auf betatest.html. Logisch?

          1. Hi,

            Irgendwie drehe ich mich aber bei dem Problem "Wie sage ich dem Server, dass er betatest.html anzeigen soll, wenn User nicht berechtigt ist und nicht sofort mit der Passwortabfrage starten soll?".

            Um es ganz genau zu machen. Mein Projekt hat DirectoryIndex index.php. Die index.php und alle Dateien, die ich nicht explizit in FilesMatch-Direktive erlaube, sollen geschützt sein. Wenn meine Url ohne explizite Angabe einer Seite aufgerufen wird, dann versucht der Server index.php aufzurufen und fragt nach dem Passwort.

            Dann widersprechen sich deine Wuensche leider.
            Wenn du willst, dass beim Abruf des Verzeichnisses die betatest.html angezeigt wird - dann definiere diese als DirectoryIndex.
            (Das wird dann aber wahrscheinlich wieder Probleme machen, wenn sich andere Verlinkungen innerhalb deiner Site darauf verlassen, ueber / die index.php zu erreichen.)

            Im Grunde genommen möchte ich den Zugriff auf index.php nur erlauben, wenn Benutzer berechtigt ist, und gleichzeitig aber die Passwortabfrage für index.php (nur diese Datei) unterbinden - bin ich nicht kompliziert? ;)

            Wie gesagt, das widerspricht sich, ist so also nicht moeglich.

            OK, der nächste Ansatz wäre mod_rewrite für Zugriff auf / bzw. index.php mit Header 401/403 und Weiterleitung auf betatest.html. Logisch?

            Wird dann auch wieder krachen, wenn weitere Referenzierungen sich darauf verlassen, unter / das Script index.php zu erreichen.

            Ein etwas umstaendlicher Workaround:
            HTTP Auth laesst sich ja (unter guenstigen Umstaenden) auch per PHP einfordern.
            Man koennte also die index.php vom Schutz per .htaccess ausnehmen, und sie "selber" danach fragen lassen, ob Benutzername und Passwort angegeben wurden und stimmen (ohne dabei aber wie im Normalfall mit 403 Forbidden zu reagieren, wenn sie nicht vorhanden sind). Wenn ja, verrichtet sie ihre gewohnte Arbeit; wenn nein, leitet sie auf die ungeschuetzte betatest.html weiter. (Das koennte man alles in einem include-File regeln, welches ganz oben eingebunden wird, und sich damit nachher leicht wieder entfernen laesst.)
            Um von der betatest.html jetzt die Passwortabfrage zu bekommen, muesste man dort natuerlich zunaechst mal auf eine andere Ressource als die index.php verlinken, denn die ist ja "ungeschuetzt" - also irgendeine andere Ressource im geschuetzten Bereich verlinken; so dass der Benutzer zur Authentifizierung aufgefordert wird, und nach dieser dann wieder auf die index.php umleiten, die im selben Realm liegend die Daten auch automatisch uebergeben bekommen sollte.

            Ob das so wirklich klappt, oder ob da irgendein Detail, welches ich jetzt nicht beruecksichtigt habe, einen Strich durch die Rechnung macht, kann ich ohne Ausprobieren nicht sagen.

            MfG ChrisB

            --
            „This is the author's opinion, not necessarily that of Starbucks.“
            1. ChrisB,

              Ein etwas umstaendlicher Workaround:
              HTTP Auth laesst sich ja (unter guenstigen Umstaenden) auch per PHP einfordern.
              Man koennte also die index.php vom Schutz per .htaccess ausnehmen, und sie "selber" danach fragen lassen, ob Benutzername und Passwort angegeben wurden und stimmen (ohne dabei aber wie im Normalfall mit 403 Forbidden zu reagieren, wenn sie nicht vorhanden sind). Wenn ja, verrichtet sie ihre gewohnte Arbeit; wenn nein, leitet sie auf die ungeschuetzte betatest.html weiter. (Das koennte man alles in einem include-File regeln, welches ganz oben eingebunden wird, und sich damit nachher leicht wieder entfernen laesst.)

              Ehrlich, eine Klasse-Lösung. Wenn ich es nicht bereits mit .htaccess gelöst hätte (reine Glücksache), hätte ich es so gemacht, da ich der PHP mächtig bin :). Ist schlüssig und nachvollziehbar. Danke.

              Ob das so wirklich klappt, oder ob da irgendein Detail, welches ich jetzt nicht beruecksichtigt habe, einen Strich durch die Rechnung macht, kann ich ohne Ausprobieren nicht sagen.

              Es ist mir gelungen, den Server zu überlisten (s. meine Antwort auf meinen ersten Post). Im Grunde ist der Ansatz ähnlich.

              Vielen Dank für Deine Hilfe und einen schönen Tag noch,
              Sonja

  2. Hallo zusammen,

    Funktionierende Lösung:

    ErrorDocument 401 /betatest.html
    ErrorDocument 403 /betatest.html
    ErrorDocument 404 /error404.html

    <FilesMatch ^(index.php)$>
    Order allow,deny
    Allow from all
    AuthName "Betatest"
    AuthType Basic
    AuthUserFile /home/www/xxxxxxxxxxxxxxxxxxxxxxxx/.htpasswd
    require valid-user
    </FilesMatch>

    <FilesMatch "(betatest.html|styles.css|logo.jpg|error404.html)$">
    Allow from All
    Satisfy any
    </FilesMatch>

    Ein Versuch die Lösung zu erklären:
    1. Mit der ersten FilesMatch-Direktive kriegt der Server zuerst die Anweisung alle Dateien (außer index.php!) mit einer Passwortabfrage zu schützen.
    2. Mit der zweiten FilesMatch-Direktive weiß der Server, dass er bestimmte aufgelistete Dateien ohne Passwortschutz zugänglich machen soll.

    Bei der index.php weiß er nicht, was er machen soll. Er liefert daher (vermutlich ???) 403 Forbidden-Meldung, die mit ErrorDocument 403 abgefangen wird und den Benutzer auf die gewünschte Startseite (betatest.html) bringt.

    In der Datei betatest.html habe ich den Link auf index.php platziert. Klickt der Benutzer drauf, so kommt die Passwortabfrage. Allerdings kommt die Passwortabfrage nicht für index.php, die ist ja nicht geschützt, sondern für die Bilder auf der Seite, die geschützt sind. Benutzer loggt sich ein und alles ist gut. Wenn Authentifizierung fehlschlägt, dann greift ErrorDocument 401 und wir sind wieder auf der Startseite.

    Vielen Dank an ALLE für die Denkanstöße!
    Gruß,
    Sonja

    1. Hi,

      In der Datei betatest.html habe ich den Link auf index.php platziert. Klickt der Benutzer drauf, so kommt die Passwortabfrage. Allerdings kommt die Passwortabfrage nicht für index.php, die ist ja nicht geschützt, sondern für die Bilder auf der Seite, die geschützt sind. Benutzer loggt sich ein und alles ist gut.

      Benutzer autheifiziert sich nicht, und bekommt damit trotzdem alle Inhalte der index.php, die nicht extern sind, zu sehen. Ist das gewollt?

      Wenn Authentifizierung fehlschlägt, dann greift ErrorDocument 401 und wir sind wieder auf der Startseite.

      Sind wir wirklich? Kann ich mir nicht vorstellen. Die index.php ist verfuegbar, die kann mein Browser also anzeigen.
      Ein paar Bilder sind nicht ungeschuetzt abrufbar, werden also im Zweifelsfalle mit 403 beantwortet, mein Browser zeigt stattdessen also ein broken image an, wenn ihm statt eines Bildes ein HTML-Dokument als 403-Antwort geliefert wird.
      Wie wir dadurch wieder auf die "Startseite" (ich nehme an, damit meinst du im jetzigen Szenario die betatest.html) gelangen, sehe ich nicht.

      MfG ChrisB

      --
      „This is the author's opinion, not necessarily that of Starbucks.“
      1. Benutzer authentifiziert sich nicht, und bekommt damit trotzdem alle Inhalte der index.php, die nicht extern sind, zu sehen. Ist das gewollt?

        Ähmm, nööö, ist nicht gewollt. Allerdings, wenn Benutzer sich nicht authentifiziert, dann bleibt er ja nicht auf index.php sonder wird mit ErrorDocument 401 auf betatest.html verwiesen.

        Sind wir wirklich? Kann ich mir nicht vorstellen. Die index.php ist verfuegbar, die kann mein Browser also anzeigen.

        Das ist es ja. Index.php ist aus irgendeinem Grund nicht verfügbar. Die Datei wird bereits beim Aufruf der URL nicht ausgegeben und der Server verweist auf betatest.html. Wahrscheinlich (?) 403-Fehler. Und wahrscheinlich bis der Benutzer sich authentifiziert. Ich kann es anders nicht erklären. Blöd und nicht ganz schlüssig, ich weiß.

        Vielleicht kann jemand mir erklären, warum es geht?

        Gruß,
        Sonja

    2. <FilesMatch ^(index.php)$>
      require valid-user

      Ein Versuch die Lösung zu erklären:

      1. Mit der ersten FilesMatch-Direktive kriegt der Server zuerst die Anweisung alle Dateien (außer index.php!) mit einer Passwortabfrage zu schützen.

      Du hast aber genau das Gegenteil gepostet. "Wenn index.php, dann require valid-user".

      1. <FilesMatch ^(index.php)$>
        require valid-user

        Ein Versuch die Lösung zu erklären:

        1. Mit der ersten FilesMatch-Direktive kriegt der Server zuerst die Anweisung alle Dateien (außer index.php!) mit einer Passwortabfrage zu schützen.

        Du hast aber genau das Gegenteil gepostet. "Wenn index.php, dann require valid-user".

        Stimmt. Oh, Gott. Da hatte ich Negation vergessen. Es geht genauso, wie ich es jetzt beschrieben habe, allerdings sind alle Unterseiten außer index.php nicht geschützt. Also mit der direkten Angaben in der Adressleiste erreichbar. :) Ich bin gut! Werde es mal mit php-Lösung von ChrisB versuchen und lasse die Finger von .htaccess, zumal ich da nicht das Wissen habe.

        Danke für Dein Hinweis!
        Sonja

      2. Ich gebe noch nicht auf. Lösung Nr. 2 mit Schutz von allen Unterseiten. Vielen Dank an Bob an dieser Stelle:

        ErrorDocument 401 /betatest.html
        ErrorDocument 403 /betatest.html
        ErrorDocument 404 /error404.html

        <FilesMatch ".(php|css|js|gif|png|jpg)$">
        Order allow,deny
        Allow from all
        AuthName "Betatest"
        AuthType Basic
        AuthUserFile /home/www/xxxxxxxxxxxxxxxxxxxxxxxx/.htpasswd
        require valid-user
        </FilesMatch>

        <FilesMatch "(betatest.html|styles.css|logo.jpg|error404.html)$">
        Allow from All
        Satisfy any
        </FilesMatch>

        Es funktioniert, wie gewünscht. Allerdings kann ich immer noch nicht nachvollziehen, warum der Server beim Aufruf der bloßen URL ohne jegliche Angaben auf betatest.html weiterleitet und keine Passwortabfrage bringt. Ich will es ja auch so, aber warum geht es überhaupt???

        Danke,
        Sonja

        1. Hi,

          Es funktioniert, wie gewünscht. Allerdings kann ich immer noch nicht nachvollziehen, warum der Server beim Aufruf der bloßen URL ohne jegliche Angaben auf betatest.html weiterleitet und keine Passwortabfrage bringt. Ich will es ja auch so, aber warum geht es überhaupt???

          Soweit ich mich (jetzt wieder) erinnere, zieht eine Files/FilesMatch-Direktive nicht, wenn die Datei nicht explizit angefordert wurde, sondern nur implizit ueber die DirectoryIndex-Einstellung.

          MfG ChrisB

          --
          „This is the author's opinion, not necessarily that of Starbucks
          1. Soweit ich mich (jetzt wieder) erinnere, zieht eine Files/FilesMatch-Direktive nicht, wenn die Datei nicht explizit angefordert wurde, sondern nur implizit ueber die DirectoryIndex-Einstellung.

            Danke. Das habe ich vermutet. Einziger Vermutstropfen ist, dass ich jetzt im Projekt, alle Links von / auf index.php ändern muss. Ist aber nicht weiter schlimm, damit kann ich leben. Und das kann so auch nach dem Betatest bleiben.

            Gruß,
            Sonja

        2. Ich gebe noch nicht auf. Lösung Nr. 2 mit Schutz von allen Unterseiten.

          Schade, dass man hier die Beiträge nicht bearbeiten kann. In meiner Lösung habe ich zwei (entscheidende?) Zeilen vergessen. Hier ist nochmal die komplette Lösung:

          ErrorDocument 401 /betatest.html
          ErrorDocument 403 /betatest.html
          ErrorDocument 404 /error404.html

          order deny,allow
          deny from all

          <FilesMatch ".(php|css|js|gif|png|jpg)$">
          Order allow,deny
          Allow from all
          AuthName "Betatest"
          AuthType Basic
          AuthUserFile /home/www/xxxxxxxxxxxxxxxxxxxxxxxx/.htpasswd
          require valid-user
          </FilesMatch>

          <FilesMatch "(betatest.html|styles.css|logo.jpg|error404.html)$">
          Allow from All
          Satisfy any
          </FilesMatch>

          Die zwei Zeilen sind vor der ersten FilesMatch-Direktive platziert. Die zwei sind auch dafür verantwortlich, dass index.php über DirectoryIndex 403-Fehler wirft (glaube ich jedenfalls).

          Und nun lasse ich Euch in Ruhe :)
          Danke noch mal.
          Sonja

          1. order deny,allow
            deny from all

            Die zwei Zeilen sind vor der ersten FilesMatch-Direktive platziert. Die zwei sind auch dafür verantwortlich, dass index.php über DirectoryIndex 403-Fehler wirft (glaube ich jedenfalls).

            Ja. Du kommst nämlich dadurch gar nicht zu der Phase, wo DirectoryIndex ausgewertet wird, da zuvor der access check gleich im 403 forbidden durch das deny from all endet.

  3. Hallo nochmal,

    ich schon wieder. Nur noch eine Frage. Die von mir gebrachte Lösung hat noch einen Nachteil. Auf das Projekt zeigen mehrere Domains (alle über VirtualHost in das selbe Verzeichnis). Wenn der Benutzer sich über eine Domain authentifiziert hat und dann über URL die andere Domain aufruft, die auf das gleiche Verzeichnis und gleiche Inhalte verweist, kommt wieder die Passwortabfrage.

    Heißt es, dass die .htacces sich die Domainnamen "merkt" und wenn der Zugriff über eine andere URL vom selben Browser in der selben Session auf die selben Inhalte stattfindet, dann muss der Benutzer sich neu authentifizieren? Oder habe ich es in der Hand?

    Danke für Eure Hilfe,
    Sonja

    1. Hi,

      Heißt es, dass die .htacces sich die Domainnamen "merkt" und wenn der Zugriff über eine andere URL vom selben Browser in der selben Session auf die selben Inhalte stattfindet, dann muss der Benutzer sich neu authentifizieren?

      Der *Browser merkt sich die ein mal eingegebenen Daten, und sendet beim naechsten Request nach einer Ressource unterhalb des gleichen Realm wieder mit.
      Natuerlich merkt er sich die Daten aber nur fuer die aktuelle Domain - denn wenn du dich auf einer Domain authentifiziert hast, moechtest du ja kaum, dass er sie auch an die naechste x-beliebige Domain, die du ansurfst, ebenso automatisch sendet.

      Oder habe ich es in der Hand?

      Nein.

      MfG ChrisB

      --
      „This is the author's opinion, not necessarily that of Starbucks.“