Michael27: Zugriff auf bestimmte Dateien nur bestimmten Usern erlauben

Hallöchen,

ich speichere auf meinem Server Rechnungen im pdf-Format. Diese sollen Kunden später in Ihrem Account (solange sie eingeloggt sind) herunterladen können.
Andere Kunden (also mit anderer User_id) sollen ebenfalls nur ihre eigenen und keine fremden Rechnungen herunterladen dürfen.
Frage: Wie kann ich das realisierien, ohne für jeden User den Dateinamen mit kryptischen Zeichen zu versehen (damit andere User den Dateinamen nicht "erraten" können)?

Vielen Dank im Voraus

  1. Hello,

    ich speichere auf meinem Server Rechnungen im pdf-Format. Diese sollen Kunden später in Ihrem Account (solange sie eingeloggt sind) herunterladen können.
    Andere Kunden (also mit anderer User_id) sollen ebenfalls nur ihre eigenen und keine fremden Rechnungen herunterladen dürfen.
    Frage: Wie kann ich das realisierien, ohne für jeden User den Dateinamen mit kryptischen Zeichen zu versehen (damit andere User den Dateinamen nicht "erraten" können)?

    Da gibt es unterschiedliche Vorgehensweisen.
    Ich setze jetzt mal voraus, dass der Zugriff per HTTP oder HTTPS stattfindet.

    Dann kann man die Files in einzelne Verzeichnisse sortieren und den Usern nur nach erfolgreicher Authentifikation Zugriff darauf gewähren. Das geht im Direktzugriff bei Apacheservern mittels "Basic Auth" oder "Digest Auth"
    http://httpd.apache.org/docs/current/howto/auth.html

    Wenn Du nicht auseinandersortieren willst, dann kannst Du auch über eine <Files>-Direktive oder <FilesMatch>-Diektive die Rechte für einzelne Files festlegen.
    http://httpd.apache.org/docs/current/mod/core.html#files
    http://httpd.apache.org/docs/current/mod/core.html#filesmatch

    Alternativ kannst Du den Zugriff auch über Scripte regeln, also die Files nicht mehr direkt über HTTP/s ausliefern, sondern indirekt über ein Script, das vorher die Authentifizierung prüft.

    Das gewählte Verfahren hängt unter anderem auch davon ab, ob Cookies benutzt werden dürfen, oder nur die Standardauthentifizierungen des Webservers.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
  2. Hallo,

    Frage: Wie kann ich das realisierien, ohne für jeden User den Dateinamen mit kryptischen Zeichen zu versehen (damit andere User den Dateinamen nicht "erraten" können)?

    "security by obscurity" wäre sowieso eine ganz schlechte Idee.

    Im Prinzip kann man es so angehen:
     * Alle in Frage kommenden Dateien liegen in einem Verzeichnis, auf das kein direkter Zugriff über
       HTTP möglich ist (außerhalb Document Root, oder durch .htaccess gesperrt).
     * Du hast sowieso schon ein Login, also ist z.B. die Kundennummer des aktuell anfragenden Besuchers
       bekannt. Ein Script (PHP, Perl oder ähnlich) bietet dem Besucher nun *nur* die Dateien zum
       Download an, die für ihn bestimmt sind (Info im Dateinamen, in einer DB oder einer separaten
       Datei), und reicht sie einfach durch.
    Mit welcher Scriptsprache möchtest du es realisieren? PHP dürfte die populärste sein.

    So long,
     Martin

    --
    Es existiert kein Weg, "für" etwas zu optimieren, sondern nur gegen alles andere.
      (Cheatah)
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. Hallo,

      da war ich wohl zu langsam ;-)

      Viele Grüße Novi

      --
      "(...) deshalb mag ich Binärtechnik. Da gibt es nur drei Zustände: High, Low und Kaputt." (Wau Holland)
    2. Danke für die ganzen Antworten bisher.
      Ich benutze in der Tat php und weiß über die UserId, ob ein Benutzer gerade
      authorisiert ist oder nicht.
      Die pdf-Rechnungen kann ich problemlos in einem öffentlich nicht zugänglichen Ordner speichern. Wie soll ich allerdings das pdf dann konkret "durchreichen" wie du meintest?

      Hallo,

      Frage: Wie kann ich das realisierien, ohne für jeden User den Dateinamen mit kryptischen Zeichen zu versehen (damit andere User den Dateinamen nicht "erraten" können)?

      "security by obscurity" wäre sowieso eine ganz schlechte Idee.

      Im Prinzip kann man es so angehen:
      * Alle in Frage kommenden Dateien liegen in einem Verzeichnis, auf das kein direkter Zugriff über
         HTTP möglich ist (außerhalb Document Root, oder durch .htaccess gesperrt).
      * Du hast sowieso schon ein Login, also ist z.B. die Kundennummer des aktuell anfragenden Besuchers
         bekannt. Ein Script (PHP, Perl oder ähnlich) bietet dem Besucher nun *nur* die Dateien zum
         Download an, die für ihn bestimmt sind (Info im Dateinamen, in einer DB oder einer separaten
         Datei), und reicht sie einfach durch.
      Mit welcher Scriptsprache möchtest du es realisieren? PHP dürfte die populärste sein.

      So long,
      Martin

      1. Ich zitiere einfach mal von php.net:

        "<?php
        // Wir werden eine PDF Datei ausgeben
        header('Content-type: application/pdf');

        // Es wird downloaded.pdf benannt
        header('Content-Disposition: attachment; filename="downloaded.pdf"');

        // Die originale PDF Datei heißt original.pdf
        readfile('original.pdf');
        ?>" (http://de.php.net/manual/de/function.header.php)

        Ich denke, dass dir das schon weiterhelfen sollte.

        Viele Grüße Novi

        --
        "(...) deshalb mag ich Binärtechnik. Da gibt es nur drei Zustände: High, Low und Kaputt." (Wau Holland)
        1. Hallo,

          readfile('original.pdf');

          wobei hier noch anzumerken wäre, dass PHP selbstverständlich auch auf Dateien und Verzeichnisse zugreifen kann, die nicht für HTTP gesperrt sind - hier findet ja kein HTTP-Zugriff statt.

          Ciao,
           Martin

          --
          Programmierer (m), seltener auch P~in (w):
          Irdische, i.a. humanoide Lebensform, die in einem komplizierten biochemischen Prozess Kaffee, Cola und Pizza in maschinenlesbaren Programmcode umwandelt.
          P~ bilden gelegentlich mit ihresgleichen kleine Gruppen, sogenannte Communities, sind aber ansonsten meist scheue Einzelgänger.
          P~ sind vorwiegend nachtaktiv und ohne technische Hilfsmittel nur eingeschränkt lebensfähig.
          Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
          1. wobei hier noch anzumerken wäre, dass PHP selbstverständlich auch auf Dateien und Verzeichnisse zugreifen kann, die nicht für HTTP gesperrt sind - hier findet ja kein HTTP-Zugriff statt.

            Aber nur wenn die Rechte auf dem Webserver passen ;)

            1. Sauber, vielen Dank für die vielen Antworten.
              Ich werde das jetzt so probieren: pdfs in einem Ordner speichern, der nicht im DocumentRoot liegt. Dann werde ich es mit readfile('original.pdf'); probieren auszugeben, so wie Novi in seinem Post geschrieben hat.
              Ich geb später mal Rückmeldung :)

              1. Hello,

                Sauber, vielen Dank für die vielen Antworten.

                Ich werde das jetzt so probieren: pdfs in einem Ordner speichern, der nicht im DocumentRoot liegt. Dann werde ich es mit readfile('original.pdf'); probieren auszugeben, so wie Novi in seinem Post geschrieben hat.

                Das ist sicherlich die vernünftigste Lösung, hat nur einen Nachteil:
                Die blockweise (chunked) Ausgabe wird dann nicht mehr unterstützt und die ist gerade bei PDF's nicht unwichtig, weil es meistens Megabyteklötze sind.

                Man kann das aber auch in PHP-Scripten nachbilden. Dies fängt aber schon bei der Auswertung der Request-Header an.

                Liebe Grüße aus dem schönen Oberharz

                Tom vom Berg

                --
                 ☻_
                /▌
                / \ Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
      2. Hello,

        Danke für die ganzen Antworten bisher.
        Ich benutze in der Tat php und weiß über die UserId, ob ein Benutzer gerade
        authorisiert ist oder nicht.
        Die pdf-Rechnungen kann ich problemlos in einem öffentlich nicht zugänglichen Ordner speichern. Wie soll ich allerdings das pdf dann konkret "durchreichen" wie du meintest?

        Da schaust Du einfach mal ins PHP-Handbuch unter readfile().
        Dort gibt es ein Beispiel
        http://de.php.net/manual/en/function.readfile.php

        Und vergiss nicht, auch das hiesige Archiv danach zu befragen. Es gibt nämlich noch etliche Sonderfälle und Zusatzbemerkungen dazu. "Download" wäre ein Suchbegriff...

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
  3. Hallo,

    ich würde die Rechnungen alle in einem Ordner speichern, auf den niemand über das HTTP-Protokoll zugreifen kann. Dies lässt sich zum Beispiel leicht über eine .htaccess Datei mit folgendem Inhalt lösen: Deny from all.

    Dies bedeutet aber nicht, dass Scripte/Programme auf deinem Server nicht darauf zugreifen können. Also kannst du einfach ein Script/Programm schreiben, dass die Rechte überprüft und gegebenenfalls die Datei aus dem Verzeichnis ausliest und an den Browser sendet.

    Viele Grüße Novi

    --
    "(...) deshalb mag ich Binärtechnik. Da gibt es nur drei Zustände: High, Low und Kaputt." (Wau Holland)
  4. Die Kunden kann man per ID son ziemlich genau bestimmen. Man könnte die pdf Datein in einen Ordner packen der diese ID hat und dann diese beim login abrufen. .htacces um diese von außen zu schützen würde ich auch empfehlen.

    1. Die Kunden kann man per ID son ziemlich genau bestimmen. Man könnte die pdf Datein in einen Ordner packen der diese ID hat und dann diese beim login abrufen. .htacces um diese von außen zu schützen würde ich auch empfehlen.

      ".htaccess" (gemeint ist sicher mod_auth_*) ist kein zuverlässiger Schutz und ganz sicher nicht empfehlenswert - sollte aus irgendwelchen Umständen dieser Schutz versagen, liegen die Dokumente offen im Netz.

      Aus diesem Grund ist es _empfehlenswert_ die Dokumente außerhalb des DocumentRoot zu platzieren.

      Dokumente in einem durch mod_auth_* geschützen Verzeichnis abzulegen ist höchstens die Ausweichlösung falls man keine bessere Möglichkeit hat.

      1. Hi,

        ".htaccess" (gemeint ist sicher mod_auth_*) ist kein zuverlässiger Schutz

        außer HTTP AUTH kommt natürlich auch noch ein brachiales Deny From All in Frage.
        Der Schutz ist natürlich unter den Umständen, die du ansprichst (Anweisungen in der .htaccess werden aus irgendwelchen Gründen nicht berücksichtigt) ebenfalls futsch.

        Aus diesem Grund ist es _empfehlenswert_ die Dokumente außerhalb des DocumentRoot zu platzieren.

        Ja.

        Dokumente in einem durch mod_auth_* geschützen Verzeichnis abzulegen ist höchstens die Ausweichlösung falls man keine bessere Möglichkeit hat.

        Einen kleinen Strohhalm gibt's noch, an den man sich klammern kann: Man benennt die Dateien so, dass der Name mit ".ht" beginnt. Diese Dateien sind nämlich auch in der Defaultkonfiguration des Apachen schon ausgenommen und werden weder in einem Verzeichnislisting gezeigt (sollte es einmal dazu kommen), noch auf direkte Anfrage ausgeliefert.

        Ciao,
         Martin

        --
        Treffen sich zwei Holzwürmer im Käse: "Na, auch Probleme mit den Zähnen?"
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Einen kleinen Strohhalm gibt's noch, an den man sich klammern kann: Man benennt die Dateien so, dass der Name mit ".ht" beginnt. Diese Dateien sind nämlich auch in der Defaultkonfiguration des Apachen schon ausgenommen und werden weder in einem Verzeichnislisting gezeigt (sollte es einmal dazu kommen), noch auf direkte Anfrage ausgeliefert.

          Aber es gibt auch veränderte Konfigurationen, darum warnt die Apache-Doku auch davor das Passwort-File (welches üblicherweise .htpasswd oder ähnliches heisst) im DocumentRoot (oder darunter) liegen zu lassen.

  5. hi,

    Frage: Wie kann ich das realisierien, ohne für jeden User den Dateinamen mit kryptischen Zeichen zu versehen (damit andere User den Dateinamen nicht "erraten" können)?

    Einen 'Dateinamen' sollte der User gar nicht erst zu Gesicht bekommen, die Datei wird serverseitig erzeugt, wie das geht, haben die Anderen schon beschrieben und wie die (temporär) heißt, ist egal.

    Wenn Du ohnehin mit Session arbeitest, programmiere es so, dass der User allenfalls nur die SessID sehen kann (im Cookie).

    Hotti