9
votes

Sécuriser de grands téléchargements en utilisant C # et IIS 7

Voici la configuration:

  • 1 serveur Web exécutant une application C # à laquelle mes utilisateurs (stockés dans une base de données MySQL sur ledit serveur) s'authentifient.

  • 1 Logiciel de serveur de fichiers TBD. Dans le passé, j'ai utilisé Lightpd et Mod_sectDownload pour sécuriser les fichiers sur les serveurs de fichiers et bien fonctionnent bien (ish).

    Je me demande s'il y a un moyen de faire cela en utilisant une combinaison d'IIS et C # .NET. Tous mes autres serveurs fonctionnent ce combo, et cela simplifierait les choses un peu si je pouvais faire la même chose pour les serveurs de fichiers. Le kicker est, les fichiers hébergés sont grands. J'ai vu des exemples de personnes utilisant une petite application pour créer un objet FileStream, lire dans le fichier et créer la réponse HTTP à la main. Cela fonctionne, mais depuis que je travaille avec des fichiers plus de 500 milliards de MB, il est lent que Heck. Et je vais potentiellement avoir 300 utilisateurs frappant la boîte à la fois, demandant des fichiers. Ce n'est pas bon.

    Alors, quelqu'un voit un moyen de voir ça? J'essaie de créer un système plus transparent et si tous mes serveurs exécutent le même logiciel / matériel, cela rendra ma vie beaucoup plus simple. Merci d'avance pour tout conseil que vous donnez!


2 commentaires

Est votre application C # ASP.NET WebForms ou MVC ?


L'application que les utilisateurs utilisent pour authentifier est une application Web C # .NET 3.5.


4 Réponses :


6
votes

vous savez quoi? L'article de KB est POO. Voici ma recommandation officielle:

public void StreamFile(string filePath)
{
    string fileName = Path.GetFileName(filePath);

    using (var fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        var contentLength = fStream.Length;

        if (Request.UserAgent.Contains("MSIE"))
        {
            Response.AddHeader("Content-Transfer-Encoding", "binary");
        }

        Response.ContentType = "application/octet-stream";
        Response.AddHeader("Content-Length", contentLength.ToString());

        // Even though "Content-Disposition" should have an upper-case "d", as per http://www.ietf.org/rfc/rfc2183.txt
        // IE fails to recognize this if the "d" is upper-cased.
        Response.AddHeader("Content-disposition", "attachment; filename=" + fileName);

        var buffer = new byte[8192];

        while (Response.IsClientConnected)
        {
            var count = fStream.Read(buffer, 0, buffer.Length);
            if (count == 0)
            {
                break;
            }

            Response.OutputStream.Write(buffer, 0, count);
            Response.Flush();
        }
    }

    Response.Close();
}


8 commentaires

Après avoir donné une tentative, il me semble que comme cela charge toujours le fichier en mémoire. Au moins, je sortais des exceptions de mémoire lorsque je l'ai essayé sur un fichier de 1,5 Go et je me suis fatigué d'attendre le téléchargement sur 450 Mo. Je fais cela sur une machine à tester, pas le serveur de fichiers, de sorte que la quantité de mémoire que je doive fonctionner est plus faible. Mes serveurs de fichiers ont une tonne de RAM (24 Go, je pense), mais je voudrais une solution qui ne nécessite pas beaucoup de contrainte sur le processeur ou la mémoire. LightPD est-ce que cela utilise des règles mod_sectDownload et URL réécrire, qui est rapide et bon marché sur les cycles / la mémoire.


@John - La manière dont j'ai lu le code dans le réflecteur, aucune des méthodes MS pour la rédaction de fichiers n'utilise réellement de petits tampons. Ils semblent tous allouer un seul tampon pour l'ensemble du fichier. Certaines de cela sont assez difficiles à tracer, alors peut-être que je manque quelque chose.


@John: Vous m'avez battu. Je viens de tester cela, et ça a fonctionné. S'il y a une solution qui ne nécessite pas de créer des flux http à la main et de prendre la mémoire, ce qui serait préféré. Lightpd le fait et le fait bien, mais j'essaie de garder le nombre de technologies impliquées au minimum. Pour l'instant, je suppose que cela fonctionne. Si quelqu'un entre sur un moyen de le faire sans le code laid filtream, cela va basculer. Mais pour l'instant, John's est la réponse acceptée.


@Sheep: Veuillez ne pas utiliser le code directement à partir de l'article de KB du lien de Ray. Les deux sont des versions très désordonnées du code que j'ai ci-dessus. En outre, j'ai une solution de bogue pour l'une des bizarreries d'IE.


@Sheep Slapper: Gardez à l'esprit la façon dont les œuvres ASP.NET, vous ne pouvez pas le faire aussi agréable que Lightpd. Le processus de travail envoie des données à ISAPI qui l'envoie à l'utilisateur. Deux endroits avec tampon sont ce que vous devrez vivre.


Est également que je suggère un tampon plus grand que 1024? Peut-être 4k ou 64k?


@sixletter: Ouais, mais il essayait de rester bas sur l'utilisation de la mémoire. Je suis sûr que 1024 octets seraient suffisants pour pénétrer la bande passante.


1k dans une boucle avec une couleur est assez inefficace.



0
votes

Vous pouvez être intéressé par le service de transfert intelligent de Fond de Microsoft (BITS).

http://msdn.microsoft.com /en-us/library/bb968799%28vs.85%29.aspx

Version 2.5 Authentification HTTP introduite via des certificats.


0 commentaires

1
votes

Ce fil a ma solution pour garder l'utilisation de la mémoire bas lorsque les utilisateurs téléchargent des fichiers. Vous voulez probablement un tampon plus gros que mon échantillon utilise, cependant.


1 commentaires

Après avoir lu que le fil et l'article de support Microsoft dans la réponse ci-dessus, je suis dirigé dans cette direction pour une solution temporaire. C'est mieux en ce sens qu'il y a moins d'applications dans le processus, mais ce n'est pas aussi transparent dans ce qui se passe. Maintenant, je dois juste développer une infime application pour la mettre en œuvre et construire ma propre version de mod_sectDownload puisque l'application qui valide que mes utilisateurs ne figurent pas sur les serveurs de fichiers! Merci pour l'info!



0
votes

Bien que cela ne soit pas directement applicable puisque vous utilisez MySQL, mais également à prendre en compte (peut même être disponible gratuitement à l'aide de SQL Server 2008 Express). SQL Server 2008 offre la prise en charge de FileStream qui vous permet d'accéder aux fichiers comme si elles sont directement stockées dans la base de données, mais résident réellement sur un service de fichiers. Ensuite, les informations sur les autres messages peuvent vous aider à l'obtenir à l'utilisateur.

Stockage FileStream dans SQL Server 2008


0 commentaires