Seite 2 von 2

Re: Download-Dateien schützen (kein Zugriff über Direkt-URL)

Verfasst: Do 8. Jul 2021, 14:08
von r_kempf
Hallo zusammen,

der Thread ist zwar schon älter - aber meine Frage ist, wann es einen Eintrag hierzu in der neuen WE-Doku für das schützen von Download-Dateien - in meinem Fall PDFs - gibt.

Der alte Link führt auf 404 Seite:
http://documentation.webedition.org/wik ... -customers

Ich komme in WE 9 mit dem alten Script nicht weiter. Es wäre prima, wenn ihr kurz schildern könntet, wie die genaue Vorgehensweise ist.

Danke und LG Regina

Re: Download-Dateien schützen (kein Zugriff über Direkt-URL)

Verfasst: Do 8. Jul 2021, 14:43
von Finn
Moin Regina,

wir verfolgen den Ansatz die Dateien anhand von Verzeichnissen zu schützen, deswegen musst du es eventuell ein bisschen für dich ändern.

Es gibt interne Dokumente, diese liegen beispielsweise unter /media/intern/.
In dem internen Verzeichnis liegt eine htaccess die alle Zugriffe blockt.

Hier die Ausgabe einer Liste mit Downloads, sowohl intern als auch öffentlich. Wir prüfen ob Dateien in einem Verzeichnis "intern" liegen und schreiben in dem Fall einen Link auf eine Datei, der die ID des Dokuments angehängt wird.

Für Nutzer die nicht eingeloggt sind, gibt es entsprechend eine andere Darstellung der Datei (ein Schloss)

Die Includes in den Links sind SVGs, die kannst du ignorieren :)

Code: Alles auswählen


	<ul class="downloads">
						<we:block name="download">
							<we:ifNotEmpty name="download">
								<we:link name="download" only="href" to="global" nameto="downloadPath"/>
								<we:ifVar type="global" name="downloadPath" match="/intern/" operator="contains">
									<we:ifNotRegisteredUser>
										<li class="item locked trigger-login">
											<span><we:link name="download" only="text"/> <we:include type="template" id="79" /> <we:include type="template" id="63" /></span> 
										</li>
										<we:else />
										<li class="item">
											<a href="/_extras/helper/download.php?f=<we:link name="download" only="id"/>" download><we:link name="download" only="text"/> <we:include type="template" id="63" /></a>
										</li>
									</we:ifNotRegisteredUser>

									<we:else />
									<li class="item">
										<a href="<we:link name="download" only="href"/>" download><we:link name="download" only="text"/> <we:include type="template" id="63" /></a>
									</li>
								</we:ifVar>
							</we:ifNotEmpty>
						</we:block>
					</ul>

Die downloads.php bekommt also die Anfrage mit der ID und kann jetzt, je nach Berechtigung die Datei zurückgeben oder eben nicht.
Geht bestimmt noch schöner, aber funktioniert auch in der 9.0.8 noch super!

Code: Alles auswählen


<we:sessionStart />
<?php
if( isset($_GET["f"]) ) {
	$id = (int)$_GET["f"];
	$file_name = $_SERVER["DOCUMENT_ROOT"] . '' . id_to_path($id);
	$protected = false;
	if( false === strpos($file_name, '/media/downloads') ) { die('this is the end...'); }
?>
<we:ifNotRegisteredUser>
	<?php if( false !== strpos($file_name, '/intern/') ) { $protected = true; } ?>
</we:ifNotRegisteredUser>
<?php
	if (!$protected && file_exists($file_name)) {
		header("Content-type: application/x-download");
		header("Content-Disposition: attachment; filename=" . basename($file_name));
		header("Content-Transfer-Encoding: binary");
		header("Content-Length: " . filesize($file_name));
		ob_clean();
		flush();
		readfile($file_name);
	}
	else if( $protected && file_exists($file_name) ) {
		if( $_SERVER['HTTPS'] ) { $protokoll = 'https://'; } else { $protokoll = 'http://'; }
		$referer = $_SERVER['HTTP_REFERER'];
		$domain = $_SERVER['SERVER_NAME'];
		$params = '?lgn';
		
		$referer = str_replace(strstr($referer, '?'), $params, $referer);

		if( strpos($referer, $domain) === false ) { $url = $protokoll . $domain . '/' . id_to_path(742) . $params; } 
		else { $url = $referer; }
		
		header('Location: ' . $url);
	}
	else {
		echo 'Error 404 :-( file not found!';
	}
}
?>


Ein Beispiel wie das ganze aussieht, findest du hier (weiter unten auf der Seite): https://relaunch.landesfrauenrat-hb.de/module.php

Hilft dir das weiter?

Re: Download-Dateien schützen (kein Zugriff über Direkt-URL)

Verfasst: Do 8. Jul 2021, 16:15
von r_kempf
Danke, Finn, aber ich brauche das stinknormale Script für ein Verzeichnis mit PDF-Dateien, das nur eingeloggten Kunden zugänglich sein soll:
Die Datei wird über einen Link im Login-Bereich aufgerufen:

Code: Alles auswählen

<a href="/pdf/download-datei.pdf" target="_blank"></a>
Meine htaccess-Datei im Verzeichnis /pdf/:

Code: Alles auswählen

RewriteEngine on
RewriteBase /
# Alle Dateiaufrufe in diesem Verzeichnis werden an die
# Datei "download-sperre.php" umgeleitet. Der Pfad zur angeforderten
# Datei wird als Parameter "file" weitergegeben.

RewriteRule (.+) /download-sperre.php?file=$1
RewriteCond %{REQUEST_FILENAME} !download-sperre.php
download-sperre.php sieht so aus:

Code: Alles auswählen

<we:sessionStart/><we:ifRegisteredUser><?php
	$str_file = (string) $_GET['file'];
	// Grobe Manipulationen am Pfad abfangen
	$str_file = str_replace('../', '..', $str_file);
	$str_file = $_SERVER['DOCUMENT_ROOT'].'/pdf/'.$str_file;
	// Nur wenn die angeforderte Datei auch existiert...
	if (is_readable($str_file))
	{
		// Download-Header setzen
		header('Content-Type: application/octet-stream');
		header('Content-Disposition: attachment; filename="'.basename($str_file).'"');
		// Datei einlesen und ausliefern (ausgeben)
		readfile($str_file);
	}
	?>
	<we:else/>
	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	<html xmlns="http://www.w3.org/1999/xhtml">
		<head>
			<we:title></we:title>
			<we:description/>
			<we:keywords/>
			<we:charset defined="UTF-8">UTF-8</we:charset>
		</head>
		<body>
			<h1>Zugriff verweigert</h1>
			<p>
				Sie haben nicht die Berechtigung, um auf diese Datei zuzugreifen.
			</p>
		</body>
	</html>
</we:ifRegisteredUser>
Leider funktioniert der Download auch nicht für eingeloggte Kunden, es wird immer alles nach<we:/else> ausgegeben. Es scheint so, als würde die session verloren gehen!?
Hat jemand eine Idee, was ich falsch mache?

Re: Download-Dateien schützen (kein Zugriff über Direkt-URL)

Verfasst: Do 8. Jul 2021, 16:59
von mokraemer
Aufpassen. Hier kann dein Test fehlerhaft sein. Wenn dein Browser die Datei gerade heruntergeladen hat, dann ist sie im Cache und er lädt sie nicht erneut runter, sondern zeigt sie nur wieder an.
Ich rate dazu unbedingt einen 2. Browser als Test. Ansonsten würde ich beim redirect auf die Datei vorher testen und kein encoding des Dateinamens erlauben:

Code: Alles auswählen

RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} "\.(pdf|doc|docx|dot|dotx|ppt|pptx|xls|xlsm|xlsx|xlt|xltm)$"
        RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -f
        RewriteRule . /-static/protectFile.php?file=%{DOCUMENT_ROOT}%{REQUEST_FILENAME} [B,L]
Beim Download empfiehlt es sich ebenfalls etags, und Caching Einstellungen zu setzen. Wenn man den Contentype stupide auf x-download setzt hat der User keine Chance den im Browser integrierten PDF-Reader zu nutzen. Man sollte hier unbedingt den richtigen ct ermitteln - ich kann ja mal die Doku anpassen - ist ja auch wieder so ein Fall wo es besser in der Doku wäre, statt hier wieder alles aufzuschreiben, oder???

Re: Download-Dateien schützen (kein Zugriff über Direkt-URL)

Verfasst: Do 8. Jul 2021, 17:53
von ThomasGoebe
mokraemer hat geschrieben: Do 8. Jul 2021, 16:59 - ist ja auch wieder so ein Fall wo es besser in der Doku wäre, statt hier wieder alles aufzuschreiben, oder???
Auf jeden Fall... ich selbst warte nach Absprache bis nach der Mitgliderversammlung mit weiteren Doku arbeiten ab. Da ist die Aufgabenverteilung so weit ich weiss Thema. Danach dann gerne wieder.

Re: Download-Dateien schützen (kein Zugriff über Direkt-URL)

Verfasst: Do 8. Jul 2021, 19:15
von r_kempf
@Marc:
Ja, ein Fall für die Doku - das wollte ich auch mit anregen!

Schönen Abend
Regina