Beantwortet File Download mit Login

  • Freitag, 13. April 2012 05:01
     
     

    Auf meiner Silverlight Seite stelle ich Downloads zur Verfügung. Diese habe ich im Projekt, das die Silverlight Seite hostet.

    Einerseits habe ich eine DownloadPage von der Dateien per Hyperlink heruntergeladen werden können.

    Andererseits können über den URL www.mysilverlightsite/Downloads/[FileName] die Dateien auch heruntergeladen werden. 

    Wie kann ich den Download einschränken, dass nur eingeloggte User Dateien herunterladen können? Wie kann ich den URL www.mysilverlightsite/Downloads/[FileName] schützen, so dass die Dateien nicht durch Eingabe des URLs heruntergeladen werden können? Wie kann ich den Download von Dateien kontrollieren?

    Ich würde gerne den Download-Dialog vom System verwenden.

    Gruss

    IntegralFramework.Net

Alle Antworten

  • Freitag, 13. April 2012 08:19
     
     
    Die Frage ist etwas unklar.
     
    Einerseits gibt es eine Anwendung, in der Rechte geprüft werden können. Andererseits gibt es den WebServer, der über eine Url Dateien bereitstellen kann und dabei Rechte prüfen kann. Was soll jetzt konkret geschützt werden:
     
    - der Abruf aus der Anwendung?
    - der Zugriff der Anwendung auf den WebServer?
    - der Zugriff auf den WebServer aus einer anderen Anwendung (z.B. Browser)?
     
    --
    Viele Gruesse
    Peter
  • Freitag, 13. April 2012 08:54
     
     

    Hallo Peter

    Die Silverlight Seite soll Downloads von Installationsdateien für registrierte User zur Verfügung stellen.

    Der Click Event des Hyperlink Buttons kann ich handlen und die Login Daten des Users überprüfen und den Download starten, falls der User berechtigt ist, die Datei herunterzuladen. Falls jemand aber im Browser

    den URL eingibt www.myseite.ch/Downloads/[FileName] kann die Datei trotzdem, ohne Login-Daten, heruntergeladen werden; dies darf nicht sein.

    Wie kann ich einen sicheren (UserLogin) Download der Dateien gewährleisten?

    Wie kann ich verhindern, dass per URL die Dateien heruntergeladen werden können?

    Gruss Stefan

  • Freitag, 13. April 2012 13:20
     
     

    Hallo Stefan,

    Falls jemand aber im Browser den URL eingibt www.myseite.ch/Downloads/[FileName] kann die Datei trotzdem, ohne Login-Daten, heruntergeladen werden; dies darf nicht sein.

    Wie kann ich einen sicheren (UserLogin) Download der Dateien gewährleisten?

    Wie kann ich verhindern, dass per URL die Dateien heruntergeladen werden können?

    das kannst Du nur über entsprechende Änderungen in der Serverapplikation machen.

    Die Dateien dürfen nicht direkt ansprechbar sein, Du müsstest hier bspw. per ASP.NET arbeiten. Den Download kann man über einen Handler (ASHX) erledigen. Dieser hört dann bspw. auf alles, was in einem bestimmten Verzeichnis angesprochen wird (das lässt sich über die web.config mit einem entsprechenden <location> Node angeben). Im Handler prüfst Du bspw. auf eine bestimmte Sessionvariable, die im Vorfeld beim Login gesetzt wurde. Falls der User berechtigt ist, die angeforderte Datei herunterzuladen, lieferst du die Datei per Response.TransmitFile( "~/Datei..." ) aus, ansonsten dann halt eine entsprechende Meldung.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


  • Freitag, 13. April 2012 14:19
     
     

    Danke Stefan!

    Das ist eine gute Antwort.

    Den Download möchte ich eigentlich per Silverlight, HyperlinkButton machen, damit der Download-Dialog von Windows erscheint; dort kann ich den Login auch einfach prüfen. 

    Ich bin neu in der Web-Entwicklung, bin in WinForms und WPF  zu Hause. Dürfen also die Download-Dateien gar nicht erst im Host-Projekt (ASP.Net) zur Verfügung stehen, weil sie sonst immer per URL ansprechbar sind oder kann ich den Zugriff von aussen irgendwie verhindern?

    Wo soll ich die Download Dateien auf dem Server legen? Gibt es Ordner, die von "aussen" per URL nicht ansprechbar sind, aber intern aus der Silverlight Applikation?

    Grundsätzlich will ich den Zugriff vom Client her per URL verhindern, so dass ich die Kontrolle über den Download behalte, was beim Hyperlink möglich ist. Oder kann ich den File-Zugriff per Event abfangen?

    Gruss Stefan

  • Freitag, 13. April 2012 14:30
     
     Beantwortet

    Hallo Stefan,

    Den Download möchte ich eigentlich per Silverlight, HyperlinkButton machen, damit der Download-Dialog von Windows erscheint;

    das kannst Du ja. Du musst dafür im Silverlight Projekt eigentlich noch nicht einmal etwas ändern, wenn serverseitig schon bekannt ist, dass der User angemeldet ist. Ansonsten müsstest Du das noch irgendwie von Silverlight aus an die Serveranwendung übermitteln.

    dort kann ich den Login auch einfach prüfen.

    Nein. Für deine Zwecke geht das eben nicht, da die Datei auf der Website liegt und von dort angefordert wird. Daher muss die Prüfung zwingend serverseitig erfolgen.

    Dürfen also die Download-Dateien gar nicht erst im Host-Projekt (ASP.Net) zur Verfügung stehen, weil sie sonst immer per URL ansprechbar sind oder kann ich den Zugriff von aussen irgendwie verhindern?

    Die Dateien dürfen schon in der Website liegen. App_Data wäre bspw. ein passender Ordner, da der standardmäßig seine Inhalte nicht per direktem Http Aufruf rausgibt.

    Den eigentlichen Aufruf für den Download Datei kannst Du aber bei http://deinserver/Downloads/Dateixyz.pdf belassen. In dem Fall würde man einen Handler einrichten, der auf sämtliche Anforderungen für eine Datei im Ordner "Downloads" reagiert, die Prüfung vornimmt und die Datei dann per

      Response.TransmitFile( String.Format( "~/App_Data/{0}", <Dateiname> ) )

    ausliefert.

    Gibt es Ordner, die von "aussen" per URL nicht ansprechbar sind, aber intern aus der Silverlight Applikation?

    Du musst Server und Client trennen. Serverseitig siehe den vorigen Punkt mit dem Ordner App_Data. Vom Client aus ist das nichts anderes als ein normaler Aufruf per Browser, da gibt es nichts, was irgendwie Zugriff auf irgendwas hätte.

    Grundsätzlich will ich den Zugriff vom Client her per URL verhindern

    Wie schon gesagt, dann bist Du zwingend darauf angewiesen, die Prüfung serverseitig zu machen.

    so dass ich die Kontrolle über den Download behalte, was beim Hyperlink möglich ist. Oder kann ich den File-Zugriff per Event abfangen?

    Siehe oben. Das, was Du möchtest, geht nicht.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

  • Freitag, 13. April 2012 15:03
     
     

    Hallo Stefan

    Der App_Data Folder ist demnach serverseitig. Diesen Folder kann ich vom Client her nicht direkt aufrufen.

    Ich sehe, dass der HttpContext in Silverlight nicht zur Verfügung steht, um Response.TransmitFile aufzurufen. Brauche ich dazu einen WCF Service oder wie kann ich auf den HttpContext zugreifen?

    Wenn ich nicht Silverlight verwenden würde und rein ASP.Net Pages hätte, dann könnte ich aus der ASP.Net Seite den Download starten per Response.TransmitFile(...) ?

    Muss ich einen WCF Service erstellen oder kann ich Response.TransmitFile() aus Silverlight aufrufen?

    Danke für Deine Geduld.

    Gruss

    Stefan

  • Freitag, 13. April 2012 21:14
     
     Beantwortet

    Hallo Stefan,

    Der App_Data Folder ist demnach serverseitig. Diesen Folder kann ich vom Client her nicht direkt aufrufen.

    Korrekt.

    Ich sehe, dass der HttpContext in Silverlight nicht zur Verfügung steht, um Response.TransmitFile aufzurufen.

    Wie gesagt: Silverlight = Client, das was Du brauchst, muss auf dem Server passieren.

    Brauche ich dazu einen WCF Service oder wie kann ich auf den HttpContext zugreifen?

    Du rufst doch von Silverlight aus nach dem Klick auf den Hyperlinkbutton und erfolgter Prüfung der Berechtigung einfach eine URL auf, oder? Falls ja, genau das musst Du weiterhin tun. Hier ändert sich nichts. Die einzige Änderung wäre dann auf dem Server. Die Datei, bspw.

      http://deinserver/Downloads/DateiAbc.pdf

    gibt es dann gar nicht mehr. Sämtliche Zugriffe auf Dateien im Ordner "Downloads" (der effektiv auch nicht mehr auf dem server vorhanden sein muss) werden über einen generischen Handler (ASHX) geschleust. Dieser Handler prüft den Request, prüft auch nochmals auf die Berechtigung und liefert dann je nach Resultat der Prüfung die Datei aus oder halt eben nicht.

    Wenn ich nicht Silverlight verwenden würde und rein ASP.Net Pages hätte, dann könnte ich aus der ASP.Net Seite den Download starten per Response.TransmitFile(...) ?

    Ja.

    Muss ich einen WCF Service erstellen oder kann ich Response.TransmitFile() aus Silverlight aufrufen?

    Nein. Du kannst das nicht von Silverlight aus aufrufen. Du sagst dem Browser lediglich, dass er - wie bisher auch - die Datei http://deinserver/Downloads/DateiAbc.pdf aufrufen soll.

    Eine andere Option hast Du da nicht.

    Die hier eine komplette Anwendung zu schreiben, die das gewünschte bietet, würde den Rahmen IMHO doch etwas sprengen. Probiers doch einfach mal mit den Informationen, wenn Du dann an einzelnen Stellen nicht weiter kommst, einfach nochmal hier fragen. Es gibt hier sicher auch Leute, die dir das - gegen Bezahlung - entwickeln würden.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

  • Samstag, 14. April 2012 03:17
     
     

    Hallo Stefan

    Hat mit ashx wunderbar geklappt. Herzlichen Dank!

    Gruss Stefan

  • Samstag, 14. April 2012 09:27
     
     

    Hallo Stefan,

    prima. Das freut mich. Könntest Du ggfs. für Leser, die irgendwann man mal ein ähnliches/gleiches Problem haben, deine Lösung noch etwas skizzieren? Das würde anderen Usern sicher später auch mal helfen :)


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

  • Samstag, 14. April 2012 11:08
     
     Beantwortet Enthält Code

    Hallo Stefan

    Ja, hatte noch einiges an Arbeit bis das ganze zum laufen kam; ist genau so wie Du mir geraten hast: im HttpHandler den Login-Test zu setzen. Dazu musste ich im LoginService die Login Daten in die Session schreiben, um diese vom HttpHandler wieder auslesen zu können - hoffe, das ist OK so bezüglich Kommunikation zwischen WCF Service und HttpHandler. Der Service braucht dazu das Attribute

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

    und die Web.Config

    serviceHostingEnvironmentaspNetCompatibilityEnabled="true"

    sonst ist die HttpContext Session im HttpHandler null.

    Per HyperlinkButton wird der NavigationUrl auf die Datei gesetzt und wir vom HttpHandler abgefangen.

    Der HttpHandler checkt per Session die LoginDaten und löst mit folgendem Code den Download per Download Dialog aus:

    string filePath = context.Server.MapPath(String.Format("{0}", context.Request.Path));
    
                    FileInfo downloadFile = new FileInfo(filePath);
    
                    context.Response.Clear();
                    context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", downloadFile.Name));
                    context.Response.ContentType = "application/octet-stream";
                    context.Response.WriteFile(downloadFile.FullName);
                    context.Response.Flush();
                    context.Response.Close();

    Danke nochmals für Deine Hilfe; hoffe, werde später die Lösung noch genauer beschreiben.

    Gruss, Stefan