Comment forcer HTTPS à l'aide d'un fichier web.config

220

J'ai cherché dans Google et StackOverflow en essayant de trouver une solution à cela, mais ils semblent tous se rapporter à ASP.NET, etc.

J'utilise généralement Linux sur mes serveurs mais pour ce client, j'utilise Windows avec IIS 7.5 (et Plesk 10). C'est la raison pour laquelle je ne suis pas familier avec les fichiers IIS et web.config . Dans un .htaccessfichier, vous pouvez utiliser des conditions de réécriture pour détecter si le protocole est HTTPS et rediriger en conséquence. Existe-t-il un moyen simple d'y parvenir en utilisant un fichier web.config, ou même en utilisant le module ' URL Rewrite ' que j'ai installé?

Je n'ai aucune expérience avec ASP.NET, donc si cela est impliqué dans la solution, veuillez inclure des étapes claires de mise en œuvre.

La raison pour laquelle je fais cela avec le web.config et non PHP est que je voudrais forcer HTTPS sur tous les actifs du site.

Ben Carey
la source

Réponses:

427

Vous avez besoin du module de réécriture d'URL, de préférence v2 (je n'ai pas de v1 installé, donc je ne peux pas garantir qu'il fonctionnera là-bas, mais il devrait).

Voici un exemple d'un tel web.config - il forcera HTTPS pour TOUTES les ressources (en utilisant la redirection 301 permanente):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <clear />
                <rule name="Redirect to https" stopProcessing="true">
                    <match url=".*" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

PS Cette solution particulière n'a rien à voir avec ASP.NET/PHP ou toute autre technologie car elle se fait uniquement à l'aide du module de réécriture d'URL - elle est traitée à l'un des niveaux initial / inférieur - avant que la demande n'arrive au point où votre code est exécuté.

LazyOne
la source
6
@BenCarey Vous devriez également regarder l'en- Strict-Transport-Securitytête: en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
LazyOne
22
Je recommande de changer la redirection afin qu'elle n'ajoute pas la chaîne de requête car elle fait déjà partie de {REQUEST_URI} (sinon les paramètres sont ajoutés deux fois). <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
franzo
6
Cela fonctionne, mais malheureusement aussi sur localhost. Pour éviter cela, vous pouvez l'ajouter aux <conditions>: <add input = "{HTTP_HOST}" pattern = "localhost" negate = "true" />
wezzix
5
En utilisant AWS Elastic beanstalk, cette méthode me donnait 302 Trop de redirections jusqu'à ce que je modifie: <match url=".*"/>à<match url="http://*.*" />
Kevin R.
1
@Sam Peut-être que le module de réécriture d'URL n'est pas installé? Il n'est pas fourni avec IIS par défaut, doit être installé séparément. Par exemple docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/…
LazyOne
80

Pour ceux qui utilisent ASP.NET MVC. Vous pouvez utiliser RequireHttpsAttribute pour forcer toutes les réponses à être HTTPS:

GlobalFilters.Filters.Add(new RequireHttpsAttribute());

Vous pourriez également vouloir faire d'autres choses pour sécuriser votre site:

  1. Forcer les jetons anti-contrefaçon à utiliser SSL / TLS:

    AntiForgeryConfig.RequireSsl = true;
  2. Exiger que les cookies nécessitent HTTPS par défaut en modifiant le fichier Web.config:

    <system.web>
        <httpCookies httpOnlyCookies="true" requireSSL="true" />
    </system.web>
  3. Utilisez le package NWebSec.Owin NuGet et ajoutez la ligne de code suivante pour activer Strict Transport Security (HSTS) sur le site. N'oubliez pas d'ajouter la directive Preload ci-dessous et de soumettre votre site au site HSTS Preload . Plus d'informations ici et ici . Notez que si vous n'utilisez pas OWIN, il existe une méthode Web.config sur laquelle vous pouvez lire sur le site NWebSec .

    // app is your OWIN IAppBuilder app in Startup.cs
    app.UseHsts(options => options.MaxAge(days: 720).Preload());
  4. Utilisez le package NWebSec.Owin NuGet et ajoutez la ligne de code suivante pour activer l'épinglage de clé publique (HPKP) sur le site. Plus d'informations ici et ici .

    // app is your OWIN IAppBuilder app in Startup.cs
    app.UseHpkp(options => options
        .Sha256Pins(
            "Base64 encoded SHA-256 hash of your first certificate e.g. cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=",
            "Base64 encoded SHA-256 hash of your second backup certificate e.g. M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE=")
        .MaxAge(days: 30));
  5. Incluez le schéma https dans toutes les URL utilisées. L' en-tête HTTP de la politique de sécurité du contenu (CSP) et l' intégrité des sous-ressources (SRI) ne fonctionnent pas bien lorsque vous imitez le schéma dans certains navigateurs. Il vaut mieux être explicite sur HTTPS. par exemple

    <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js">
    </script>
  6. Utilisez le modèle de projet ASP.NET MVC Boilerplate Visual Studio pour générer un projet avec tout cela et bien plus encore. Vous pouvez également afficher le code sur GitHub .

Muhammad Rehan Saeed
la source
4
La question demande ASP.NET mais n'énonce pas WebForms ou MVC, j'ai donc donné une réponse complète pour ceux qui utilisent MVC (qui n'utilise pas le fichier Web.config pour forcer HTTPS) et pourtant ... ont voté.
Muhammad Rehan Saeed
6
a) La solution fonctionne mais les choses ont changé, cette question importante et bien cotée mérite une réponse mise à jour en utilisant ce qui est intégré dans MVC. b) La réponse essaie de couvrir toutes les bases. La question n'est pas simple, activer HTTPS sur un site entier nécessite beaucoup plus que de changer un fichier web.config. Les lecteurs peuvent être induits en erreur en pensant qu'il suffit de modifier un fichier Web.config. La sécurité est déjà assez difficile car elle est sans réponses incomplètes / obsolètes.
Muhammad Rehan Saeed
11
À mon avis, c'est une excellente et précieuse réponse. Quand quelqu'un google le sujet et est dirigé vers cette question, je suis content que votre réponse soit ici.
président James K. Polk
1
@MuhammadRehanSaeed Nice post. Peut-être ajouter le SRI à votre liste? scotthelme.co.uk/subresource-integrity
Nathan
1
@MuhammadRehanSaeed true - Je suppose que votre rubrique "Autres choses que vous voudrez peut-être aussi faire pour aider à sécuriser votre site" m'a fait penser à ça :)
Nathan
14

Pour augmenter la réponse de LazyOne, voici une version annotée de la réponse.

<rewrite>
  <rules>
     <clear />
     <rule name="Redirect all requests to https" stopProcessing="true">
       <match url="(.*)" />
         <conditions logicalGrouping="MatchAll">
           <add input="{HTTPS}" pattern="off" ignoreCase="true" />
         </conditions>
         <action 
            type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" 
            redirectType="Permanent" appendQueryString="false" />
     </rule>
  </rules>
</rewrite>

Effacez toutes les autres règles qui ont peut-être déjà été définies sur ce serveur. Créez une nouvelle règle, que nous nommerons "Rediriger toutes les demandes vers https". Après avoir traité cette règle, ne traitez plus de règles! Correspond à toutes les URL entrantes. Vérifiez ensuite si toutes ces autres conditions sont remplies: HTTPS est désactivé. Eh bien, ce n'est qu'une condition (mais assurez-vous que c'est vrai). Si c'est le cas, renvoyez une redirection 301 permanente au client à l'adresse http://www.foobar.com/whatever?else=the#url-contains. N'ajoutez pas la chaîne de requête à la fin de cela, car cela dupliquerait la chaîne de requête!

C'est ce que signifient les propriétés, les attributs et certaines des valeurs.

  • clear supprime toutes les règles de serveur dont nous pourrions autrement hériter.
  • règle définit une règle.
    • nommez un nom arbitraire (quoique unique) pour la règle.
    • stopProcessing si vous souhaitez transférer la demande immédiatement vers le pipeline de demandes IIS ou d'abord pour traiter des règles supplémentaires.
  • correspond quand exécuter cette règle.
    • url un modèle par rapport auquel évaluer l'URL
  • conditions conditions supplémentaires sur le moment d'exécuter cette règle; les conditions ne sont traitées que s'il y a d'abord une correspondance.
    • logicGrouping si toutes les conditions doivent être vraies ( MatchAll) ou l'une des conditions doit être vraie ( MatchAny); similaire à AND vs OR.
  • add ajoute une condition qui doit être remplie.
    • saisir l'entrée qu'une condition évalue; l'entrée peut être des variables de serveur.
    • modèle la norme par rapport à laquelle évaluer l'entrée.
    • ignoreCase, que la capitalisation soit importante ou non.
  • action quoi faire si le matchet son conditionssont tous vrais.
    • Le type peut généralement être redirect(côté client) ou rewrite(côté serveur).
    • url quoi produire à la suite de cette règle; dans ce cas, concaténer https://avec deux variables de serveur.
    • redirectTapez la redirection HTTP à utiliser; celui-ci est un 301 permanent.
    • appendQueryString s'il faut ou non ajouter la chaîne de requête à la fin de la résultante url; dans ce cas, nous la définissons sur false, car l' {REQUEST_URI}inclut déjà.

Les variables du serveur sont

  • {HTTPS}qui est soit OFFou ON.
  • {HTTP_HOST}est www.mysite.com, et
  • {REQUEST_URI} inclut le reste de l'URI, par exemple /home?key=value
    • le navigateur gère le #fragment(voir le commentaire de LazyOne).

Voir également: https://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-configuration-reference

Shaun Luttin
la source
1
Une remarque cependant: la partie fragmentée de l'URL (de /home?key=value#fragment) n'est pas définie sur le serveur par les navigateurs car elle était destinée à être utilisée localement.
LazyOne
@LazyOne Question. Nous utilisons le web.config ci-dessus avec succès pour rediriger de greenearth.game/about#foo vers HTTPS. Le passage à HTTPS inclut le fragment #foo. Étant donné que la partie #foo n'est pas envoyée au serveur, comment la redirection l'inclut-elle?
Shaun Luttin
Il est géré par navigateur. Ouvrez simplement l'onglet réseau dans Google Chrome (ou similaire dans Firefox, etc.) et voyez quelle URL est réellement demandée (par exemple, la http://www.example.com/members#oopsdemande sera envoyée à http://www.example.com/memberslaquelle sera ensuite redirigé vers la version HTTPS à https://www.example.com/members- le navigateur fait le reste)
LazyOne
@LazyOne Merci pour cela. Si je me souviens bien, il existe quelques bogues WebKit qui empêchent le fragment d'être inclus dans les redirections. Donc, cela a du sens. bugs.webkit.org/show_bug.cgi?id=24175
Shaun Luttin
1
en.wikipedia.org/wiki/Fragment_identifier - "Les clients ne sont pas censés envoyer des fragments d'URI aux serveurs lorsqu'ils récupèrent un document, et sans l'aide d'une application locale (voir ci-dessous), les fragments ne participent pas aux redirections HTTP" - juste pour être clair au cas où j'aurais mal compris votre dernier commentaire.
LazyOne
6

La réponse acceptée n'a pas fonctionné pour moi. J'ai suivi les étapes de ce blog .

Un point clé qui me manquait était que je devais télécharger et installer l'outil de réécriture d'URL pour IIS. Je l'ai trouvé ici . Le résultat était le suivant.

<rewrite>
        <rules>
            <remove name="Http to Https" />
            <rule name="Http to Https" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
                <match url="*" />
                <conditions>
                    <add input="{HTTPS}" pattern="off" />
                </conditions>
                <serverVariables />
                <action type="Redirect" url="https://{HTTPS_HOST}{REQUEST_URI}" />
            </rule>
        </rules>
    </rewrite>
Eric
la source
1

Dans .Net Core, suivez les instructions sur https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl

Dans votre startup.cs, ajoutez ce qui suit:

// Requires using Microsoft.AspNetCore.Mvc;
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MvcOptions>(options =>
    {
        options.Filters.Add(new RequireHttpsAttribute());
    });`enter code here`

Pour rediriger Http vers Https, ajoutez ce qui suit dans le startup.cs

// Requires using Microsoft.AspNetCore.Rewrite;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    var options = new RewriteOptions()
       .AddRedirectToHttps();

    app.UseRewriter(options);
Homme oraculaire
la source
0

L'excellente bibliothèque NWebsec peut mettre à niveau vos demandes de HTTP vers HTTPS en utilisant sa upgrade-insecure-requestsbalise dans Web.config:

<nwebsec>
  <httpHeaderSecurityModule>
    <securityHttpHeaders>
      <content-Security-Policy enabled="true">
        <upgrade-insecure-requests enabled="true"  />
      </content-Security-Policy>
    </securityHttpHeaders>
  </httpHeaderSecurityModule>
</nwebsec>
Que fait-il
la source
0

Je n'étais pas autorisé à installer la réécriture d'URL dans mon environnement, j'ai donc trouvé un autre chemin.

L'ajout de cela à mon web.config a ajouté la réécriture d'erreur et a travaillé sur IIS 7.5:

<system.webServer>
    <httpErrors errorMode="Custom" defaultResponseMode="File" defaultPath="C:\WebSites\yoursite\" >    
    <remove statusCode="403" subStatusCode="4" />
    <error statusCode="403" subStatusCode="4" responseMode="File" path="redirectToHttps.html" />
</httpErrors>

Ensuite, en suivant les conseils ici: https://www.sslshopper.com/iis7-redirect-http-to-https.html

J'ai créé le fichier html qui fait la redirection (redirectToHttps.html):

<html>
<head><title>Redirecting...</title></head>
<script language="JavaScript">
function redirectHttpToHttps()
{
    var httpURL= window.location.hostname + window.location.pathname + window.location.search;
    var httpsURL= "https://" + httpURL;
    window.location = httpsURL;
}
redirectHttpToHttps();
</script>
<body>
</body>
</html>

J'espère que quelqu'un trouve cela utile car je n'ai pas pu trouver toutes les pièces au même endroit ailleurs.

Spencer Sullivan
la source
-7

Un moyen simple consiste à dire à IIS d'envoyer votre fichier d'erreur personnalisé pour les requêtes HTTP. Le fichier peut alors contenir une méta-redirection, une redirection JavaScript et des instructions avec lien, etc ... Surtout, vous pouvez toujours cocher "Exiger SSL" pour le site (ou dossier) et cela fonctionnera.

</configuration>
</system.webServer>
    <httpErrors>
        <clear/>
        <!--redirect if connected without SSL-->
        <error statusCode="403" subStatusCode="4" path="errors\403.4_requiressl.html" responseMode="File"/>
    </httpErrors>
</system.webServer>
</configuration>
réorienter
la source
Pourquoi le downvote? Cela fonctionne et répond à la question.
rediriger
14
Il s'agit d'un vote négatif, car vous dites à Google que votre fichier n'est pas trouvé, puis vous utilisez JavaScript pour rediriger, ce qui est généralement mauvais.
Thomas Bennett