web-dev-qa-db-fra.com

Comment protéger les fichiers statiques avec l'authentification par formulaire ASP.NET sur IIS 7.5?

J'ai un site Web fonctionnant sur un serveur IIS 7.5 avec ASP.NET 4.0 sur un hôte partagé, mais en toute confiance.

Le site est un "navigateur de fichiers" de base qui permet aux visiteurs de se connecter et d'afficher une liste de fichiers à leur disposition, et, évidemment, de télécharger les fichiers. Les fichiers statiques (principalement des fichiers pdf) sont situés dans un sous-dossier du site appelé données, par ex. http://example.com/data/ ...

Le site utilise l'authentification par formulaire ASP.NET.

Ma question est: comment puis-je obtenir le moteur ASP.NET pour gérer les demandes pour les fichiers statiques dans le dossier de données, de sorte que la demande de fichiers est authentifiée par ASP.NET, et les utilisateurs ne sont pas en mesure de créer un lien profond vers un fichier et récupérer des fichiers qu'ils ne sont pas autorisés à avoir?

Cordialement, Egil.

34
Egil Hansen

Si votre pool d'applications s'exécute en mode intégré, vous pouvez effectuer les opérations suivantes.

Ajoutez ce qui suit à votre web.config de niveau supérieur.

  <system.webServer>
    <modules>
      <add  name="FormsAuthenticationModule"  type="System.Web.Security.FormsAuthenticationModule" />
      <remove  name="UrlAuthorization" />
      <add  name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"  />
      <remove  name="DefaultAuthentication" />
      <add  name="DefaultAuthentication"  type="System.Web.Security.DefaultAuthenticationModule" />
    </modules>
  </system.webServer>

Vous pouvez maintenant utiliser les autorisations ASP.NET standard dans votre web.config pour forcer l'authentification par formulaires pour tous les fichiers du répertoire.

<system.web>
    <authorization>
        <deny users="?" />
    </authorization>
    <authentication mode="Forms" />
</system.web>
46
Joel Cunningham

J'ai eu le même problème pour obtenir l'authentification des rôles. Par essais et erreurs, j'ai finalement réussi à le faire fonctionner avec une petite modification du code de @Joel Cunningham:

<modules runAllManagedModulesForAllRequests="true" >

J'ai utilisé ces deux sites comme références: http://forums.iis.net/t/1177964.aspx et http://learn.iis.net/page.aspx/244/comment-profiter-du-pipeline-intégré-iis /

13
Danielle

C'est un vieux fil, mais je suis tombé dessus et j'ai rencontré le même problème que Egil. Voici la version du correctif de Joel qui inclut des rôles:

<modules runAllManagedModulesForAllRequests="false">
      <remove name="FormsAuthenticationModule" />
      <add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule" />
      <remove name="UrlAuthorization" />
      <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"  />
      <remove name="RoleManager" />
      <add name="RoleManager" type="System.Web.Security.RoleManagerModule" />
      <remove name="DefaultAuthentication" />
      <add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" />
</modules>
10
John

Addenda:

Comme @eych l'a noté, la réponse acceptée bloque également l'accès à ~/Content dossier (ou partout où vous avez votre CSS), et ~/Scripts, etc.

Si vous souhaitez autoriser des exceptions - c'est-à-dire permettre à certains fichiers/dossiers d'être accessibles par des utilisateurs non authentifiés - vous pouvez le faire au moyen de l'élément location. Ajoutez ce qui suit à web.config:

  <location path="Content">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>

pdate: Une autre solution consiste à laisser l'accès activé par défaut - ce qui permettra d'accéder à votre CSS/JavaScript/etc. - et d'appliquer le "verrou" (uniquement) au dossier où le contenu statique est stocké:

<location path="data">
  <system.web>
    <authorization>
      <deny users="?"/>
    </authorization>
  </system.web>
</location>

Avertissement: dans notre cas (un site MVC), nous devions décorer toutes nos actions de contrôleur (sauf la connexion) avec [AuthorizeAttribute]. Ce qui est une bonne idée de toute façon, mais qui n'était auparavant pas nécessaire (car auparavant toute demande non autorisée était redirigée vers la page de connexion).

8
David

Je voulais savoir pourquoi il serait nécessaire de rajouter des modules (avec des options par défaut) qui sont ajoutés par défaut pour le pipeline intégré, j'ai donc creusé un peu plus.

Vous devez supprimer et rajouter les modules car, par défaut, les modules ne sont pas ajoutés avec les options par défaut. Une condition préalable a été ajoutée pour que la compatibilité descendante ne s'exécute que pour le contenu géré par un gestionnaire ASP.NET enregistré (par exemple, les pages .aspx).

La valeur par défaut ressemble à ceci:

<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" 
         preCondition="managedHandler" />

En supprimant les modules et en les rajoutant sans condition préalable, ces modules individuels s'exécutent pour chaque demande (y compris votre contenu statique). C'est plus granulaire que d'activer runAllManagedModulesForAllRequests.

Vous pouvez lire à ce sujet dans quelques articles à partir du moment où le pipeline intégré a été introduit avec IIS 7:

Notez qu'il y a une faute de frappe ou le nom du module dans le deuxième article (et la réponse de @ John) a été changé de FormsAuthenticationModule à FormsAuthentication à un moment donné.

L'ensemble des modules de travail dans IIS 7,5 à 8,5 ressemble à ceci pour moi:

<system.webServer>
  <modules>
    <!-- Re-add auth modules (in their original order) to run for all static and dynamic requests -->
    <remove name="FormsAuthentication" />
    <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
    <remove name="DefaultAuthentication" />
    <add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" />
    <remove name="RoleManager" />
    <add name="RoleManager" type="System.Web.Security.RoleManagerModule" />
    <remove name="UrlAuthorization" />
    <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
  </modules>
</system.webServer>
8
nekno

Si votre pool d'applications s'exécute en mode classique, vous pouvez effectuer les opérations suivantes. Vous devrez répéter ces étapes pour chaque extension de fichier que vous souhaitez gérer, mais j'utilise .html ici.

Tout d'abord, ajoutez un fournisseur de création de page au Web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.web> 
    <compilation>
      <buildProviders>
        <add type="System.Web.Compilation.PageBuildProvider" extension=".html"/>
      </buildProviders>
    </compilation>
  </system.web> 
</configuration>

Ajoutez ensuite une fabrique de gestionnaires de pages:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.web> 
    <httpHandlers>
      <add type="System.Web.UI.PageHandlerFactory" path="*.html" verb="*"/>
    </httpHandlers>
  </system.web> 
</configuration>

Ajoutez ensuite un gestionnaire de page:

<?xml version="1.0" encoding="UTF-8"?>
<configuration> 
  <system.webServer>
    <handlers>
      <add scriptProcessor="C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" requireAccess="Script" preCondition="classicMode,runtimeVersionv2.0,bitness32" path="*.html" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" name="HtmlHandler-Classic-32" />
      <add scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" requireAccess="Script" preCondition="classicMode,runtimeVersionv2.0,bitness64" path="*.html" verb="GET,HEAD,POST,DEBUG" name="HtmlHandler-Classic-64"/>
    </handlers>
  </system.webServer>
</configuration>

Cela a fonctionné pour moi. (Crédit: http://www.ifinity.com.au/Blog/EntryId/66/How-To-301-Redirect-htm-or-html-pages-to-DotNetNuke-aspx-pages =.)

2
Jay Sullivan