Bir sitenin tamamı için https'yi zorlamanın en iyi yolu asp.net?


192

Yaklaşık 6 ay önce her isteğin https'nin üzerinde olması gereken bir site sundum. Bir sayfaya yapılan her isteğin https üzerinden gerçekleştiğinden emin olmak için bulabildiğim tek yol, sayfa yükleme etkinliğinde kontrol etmekti. İstek http'nin üzerinde olmasaydı response.redirect (" https://example.com ")

Daha iyi bir yol var mı - ideal olarak web.config dosyasında bazı ayarlar var mı?


Cevabımı buradan kontrol edin stackoverflow.com/questions/33882350/…
Shady Sherif

Yanıtlar:


250

Lütfen HSTS (HTTP Sıkı Aktarım Güvenliği) kullanın

dan http://www.hanselman.com/blog/HowToEnableHTTPStrictTransportSecurityHSTSInIIS7.aspx

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="HTTP to HTTPS redirect" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
                        redirectType="Permanent" />
                </rule>
            </rules>
            <outboundRules>
                <rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
                    <match serverVariable="RESPONSE_Strict_Transport_Security"
                        pattern=".*" />
                    <conditions>
                        <add input="{HTTPS}" pattern="on" ignoreCase="true" />
                    </conditions>
                    <action type="Rewrite" value="max-age=31536000" />
                </rule>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

Orijinal Yanıt (4 Aralık 2015'te yukarıdaki ile değiştirilmiştir)

temel olarak

protected void Application_BeginRequest(Object sender, EventArgs e)
{
   if (HttpContext.Current.Request.IsSecureConnection.Equals(false) && HttpContext.Current.Request.IsLocal.Equals(false))
   {
    Response.Redirect("https://" + Request.ServerVariables["HTTP_HOST"]
+   HttpContext.Current.Request.RawUrl);
   }
}

global.asax.cs (veya global.asax.vb) içinde yer alacak

i web.config içinde belirtmek için bir yol bilmiyorum


7
Bu işe yarıyor, ama benim için tehlikeliydi: VS 2010'da bu kod çalışırken yerel olarak çalıştırmayı denediğimde, başlangıç ​​sayfam hiç yüklenmedi; bunun yerine, "Bu web sayfası kullanılamıyor" iletisi aldım. Düzeltmek için, url "localhost" dizesini içerip içermediğini test etmek için ikinci bir koşul ekledim: yoksa, https'yi zorlayın.
mg1075

3
Bu bana bir yönlendirme döngüsü veriyor. Kodu eklemeden önce iyi çalıştı. Baska öneri?
Joe

9
Bunun herhangi bir yararlı güvenlik sağlamadığını lütfen unutmayın. Aslında, yalnızca zaten güvenli olan ve saldırıya uğrayanların güvenliğini sağlayamayacak bağlantıların güvenliğini sağlar (bunun nedeni, bir MITM'nin yönlendirmeyi tamamen atlaması ve her şeyi "güvenli" sitenize iletebilmesidir). IMHO, kullanıcı aracılarını yeniden yönlendirmek sadece iyi hissetmek voodoo güvenliği ve bazen tehlikeli bir güvenlik yanılsaması sağlar. Gitmenin tek yolu, kullanıcı temsilcilerine yalnızca güvenli kaynaklar istemelerini istemek, istemezlerse yönlendirmemektir. HSTS'nin yaptığı budur - aşağıdaki cevaplara bakın.
tne

2
Bu cevap 'zararlı' olarak değerlendirilmeli ve kullanılmamalıdır. Yukarıdaki @ tne tarafından yapılan yorum başına.
Rosdi Kasım

2
@RosdiKasim Bu yanıt 4 Aralık 15'ten bu yana hala zararlı kabul edilmeli mi?
Andrew Morton

123

Yapabileceğiniz diğer bir şey de "Strict-Transport-Security" başlığını tarayıcıya döndürerek HSTS kullanmaktır . Tarayıcının bunu desteklemesi gerekir (ve şu anda öncelikle Chrome ve Firefox bunu yapmaktadır), ancak bir kez ayarlandığında, tarayıcının HTTP üzerinden siteye istekte bulunmayacağı ve bunun yerine bunları yayınlamadan önce HTTPS isteklerine çevireceği anlamına gelir. . Bunu HTTP'den gelen bir yönlendirmeyle birlikte deneyin:

protected void Application_BeginRequest(Object sender, EventArgs e)
{
  switch (Request.Url.Scheme)
  {
    case "https":
      Response.AddHeader("Strict-Transport-Security", "max-age=300");
      break;
    case "http":
      var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery;
      Response.Status = "301 Moved Permanently";
      Response.AddHeader("Location", path);
      break;
  }
}

HSTS'nin farkında olmayan tarayıcılar sadece üstbilgiyi yok sayar, ancak yine de switch deyimi tarafından yakalanır ve HTTPS'ye gönderilir.


6
Daha önce HSTS başlığını hiç duymadım, ama oldukça havalı görünüyor. Böyle küçük bir maksimum yaş değerini (5 dakika) kullanmanın herhangi bir nedeni var mı? Bağlantı verdiğiniz Wikipedia makalesi, büyük bir değere (6-12 ay) ayarlanmasını önerir.
dana

5
+1. Troy'un blogunda, yalnızca yönlendirmeleri kullanmanın güvenliği neden azaltabileceğine dair ayrıntılar içeren bu çok kapsamlı makaleye göz atın. İpucu: diğer şeylerin yanı sıra sizi SSL Strip aracına karşı savunmasız bırakabilir. troyhunt.com/2011/11/…
Oran Dennison

3
Ayrıca bu (ve daha) çok kolay kılan NWebsec , kontrol değer .
Tieson T.

16
if(!Request.IsLocal)Hata ayıklamayı bozmaması için anahtarı sarmak isteyeceksiniz .
Justin J Stark

1
İyi cevap. Bir incelik - Http başlıkları ("Strict-Transport-Security") için, NWebSec gibi bir kitaplık kullanmak daha iyidir çünkü bir yapılandırma yerine burada ve oraya yayılmış birden çok seçenek vardır.
Ognyan Dimitrov

89

IIS7 modülü yeniden yönlendirmenizi sağlar.

    <rewrite>
        <rules>
            <rule name="Redirect HTTP to HTTPS" stopProcessing="true">
                <match url="(.*)"/>
                <conditions>
                    <add input="{HTTPS}" pattern="^OFF$"/>
                </conditions>
                <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther"/>
            </rule>
        </rules>
    </rewrite>

12
Ayrıca, IIS 7.0 için, Url Rewrite Module 2.0
Chris

Bu bağlantıyı, yalnızca https isteklerini kabul etmek için herhangi bir sayfayı yapmada basit ve yararlı buldum - support.microsoft.com/kb/239875
Manik Arora

21

ASP.NET MVC kullananlar için. SSL / TLS'yi HTTPS üzerinden tüm site üzerinde iki şekilde zorlamak için aşağıdakileri kullanabilirsiniz:

Zor yol

1 - RequireHttpsAttribute öğesini genel filtrelere ekleyin:

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

2 - Sahtecilikle Mücadele simgelerini SSL / TLS kullanmaya zorlayın:

AntiForgeryConfig.RequireSsl = true;

3 - Web.config dosyasını değiştirerek Tanımlama Bilgilerinin varsayılan olarak HTTPS gerektirmesini iste:

<system.web>
    <httpCookies httpOnlyCookies="true" requireSSL="true" />
</system.web>

4 - NWebSec.Owin NuGet paketini kullanın ve site genelinde Sıkı Aktarım Güvenliğini etkinleştirmek için aşağıdaki kod satırını ekleyin. Aşağıdaki Ön Yükleme yönergesini eklemeyi ve sitenizi HSTS Ön Yükleme sitesine göndermeyi unutmayın . Burada ve burada daha fazla bilgi . OWIN kullanmıyorsanız, NWebSec sitesinde okuyabileceğiniz bir Web.config yöntemi olduğunu unutmayın .

// app is your OWIN IAppBuilder app in Startup.cs
app.UseHsts(options => options.MaxAge(days: 30).Preload());

5 - NWebSec.Owin NuGet paketini kullanın ve sitede Genel Anahtar Sabitlemeyi (HPKP) etkinleştirmek için aşağıdaki kod satırını ekleyin. Burada ve burada daha fazla bilgi .

// 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));

6 - Kullanılan URL'lere https şemasını ekleyin. İçerik Güvenlik İlkesi (CSP) HTTP üstbilgisi ve Alt Kaynak Bütünlüğü (SRI) , bazı tarayıcılarda düzeni taktığınızda iyi oynatılmıyor. HTTPS hakkında açık olmak daha iyidir. Örneğin

<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js"></script>

Kolay yol

Tüm bu ve çok daha fazla yerleşik bir proje oluşturmak için ASP.NET MVC Boilerplate Visual Studio proje şablonunu kullanın. GitHub kod da görüntüleyebilirsiniz .


3
Ayrıca kullanıyorsanız <authentication mode="Forms">, içinde olması gerekir<forms requireSSL="true">
Pluto

1
@ muhammad-rehan-saeed Mvc5 boilerplate kullanıyorum ama site üretim sunucusunda otomatik olarak http https yönlendirmez, bu yüzden sadece localhost üzerinde eksik bir şey var mı?
Diin

Bu, bu soruyu sormak için doğru forum değil. GitHub sitesine bir sorun gönderin. RequireHttpsAttributeYönlendirme yapar. Sahip olduğunuz sürece iyi olmalı.
Muhammad Rehan Saeed

@MuhammadRehanSaeed, cevabınızı seviyorum. Ama ... MakeCert ile oluşturulan bir sertifikanın SHA256 karmasını nasıl alabilirim? Tek sahip olduğum şey bir SHA-1 parmak izi ... Biliyor musun?
Diana

1
@ Diana Bu bağlantı size nasıl olduğunu gösterebilir.
Muhammad Rehan Saeed

13

Herhangi bir nedenle IIS'de ayarlayamazsanız, sizin için yönlendirmeyi yapan bir HTTP modülü yaparım:

using System;
using System.Web;

namespace HttpsOnly
{
    /// <summary>
    /// Redirects the Request to HTTPS if it comes in on an insecure channel.
    /// </summary>
    public class HttpsOnlyModule : IHttpModule
    {
        public void Init(HttpApplication app)
        {
            // Note we cannot trust IsSecureConnection when 
            // in a webfarm, because usually only the load balancer 
            // will come in on a secure port the request will be then 
            // internally redirected to local machine on a specified port.

            // Move this to a config file, if your behind a farm, 
            // set this to the local port used internally.
            int specialPort = 443;

            if (!app.Context.Request.IsSecureConnection 
               || app.Context.Request.Url.Port != specialPort)
            {
               app.Context.Response.Redirect("https://" 
                  + app.Context.Request.ServerVariables["HTTP_HOST"] 
                  + app.Context.Request.RawUrl);    
            }
        }

        public void Dispose()
        {
            // Needed for IHttpModule
        }
    }
}

Daha sonra bir DLL dosyasına derleyin, projenize bir başvuru olarak ekleyin ve bunu web.config dosyasına yerleştirin:

 <httpModules>
      <add name="HttpsOnlyModule" type="HttpsOnly.HttpsOnlyModule, HttpsOnly" />
 </httpModules>

Bu sadece global.asax'a yapışmaktan daha fazla ilgili görünüyor - sadece merak ediyorum, bir avantaj var mı?
Brian MacKay

1
Avantajı, kullanmak istemediğinizde, web.config dosyasındaki modülü yorumlamanız olacaktır. Bu çözelti, bir başka değil ise, ayarlanabilir.
Bob Yexley

2
Biraz kafam karıştı. Ben bir şey gibi beklediğimden app.BeginRequest += new OnBeginRequest;de Inityöntem ve de OnBeginRequestşimdiki neyi içeriyor olur Inityöntemi içermektedir. Bu modülün beklendiği gibi çalıştığından emin misiniz?
Jakub Šturc

İşe yaramıyor. OnBeginRequest olayını vb eklemeniz gerekir, sonra çalışır.
SnAzBaZ

Bu hatalı kodu düzenlerdim, ancak güvenliğini sağlamak için HSTS'yi de kullanmanız gerekir. Sadece Troy Hunt'un cevabı ile gidin ve bir modül yapın; bkz. support.microsoft.com/en-us/kb/307996 (bir yaşlı, ama tatlım).
Marc L.

4

Yapmanız gereken:

1) Aşağıdaki gibi prodüksiyon veya sahne sunucusuna bağlı olarak web.config içine bir anahtar ekleyin

<add key="HttpsServer" value="stage"/>
             or
<add key="HttpsServer" value="prod"/>

2) Global.asax dosyanızın içine aşağıdaki yöntemi ekleyin.

void Application_BeginRequest(Object sender, EventArgs e)
{
    //if (ConfigurationManager.AppSettings["HttpsServer"].ToString() == "prod")
    if (ConfigurationManager.AppSettings["HttpsServer"].ToString() == "stage")
    {
        if (!HttpContext.Current.Request.IsSecureConnection)
        {
            if (!Request.Url.GetLeftPart(UriPartial.Authority).Contains("www"))
            {
                HttpContext.Current.Response.Redirect(
                    Request.Url.GetLeftPart(UriPartial.Authority).Replace("http://", "https://www."), true);
            }
            else
            {
                HttpContext.Current.Response.Redirect(
                    Request.Url.GetLeftPart(UriPartial.Authority).Replace("http://", "https://"), true);
            }
        }
    }
}

3

Sitenizde SSL desteği yapılandırılamıyorsa (örn. Https'yi açıp kapatabilmeniz gerekiyorsa) - güvenliğini sağlamak istediğiniz herhangi bir denetleyici / denetleyici eyleminde [RequireHttps] özelliğini kullanabilirsiniz.



2

Yukarıdaki @Joe için, "Bu bana bir yönlendirme döngüsü veriyor. Kodu eklemeden önce iyi çalıştı. Herhangi bir öneri? - Joe Nov 8 '11 at 4:13"

Bu da benim başıma geliyordu ve olduğuna inandığım şey, Web sunucusunun önünde SSL isteğini sonlandıran bir yük dengeleyici olmasıydı. Bu nedenle, orijinal tarayıcı "https" olmasını istese bile, Web sitem her zaman isteğin "http" olduğunu düşünüyordu.

Bunun biraz hileli olduğunu itiraf ediyorum, ama benim için işe yarayan, kişinin zaten bir kez yönlendirildiğini anlamak için kaldırabileceğim bir "JustRedirected" özelliği uygulamaktı. Bu nedenle, yeniden yönlendirmeyi garanti eden belirli koşulları test ediyorum ve karşılandıysa, yeniden yönlendirme öncesinde bu özelliği (oturumda depolanan değer) ayarlıyorum. Http / https yeniden yönlendirme koşulları ikinci kez karşılansa bile, yeniden yönlendirme mantığını atlayıp "JustRedirected" oturum değerini false olarak sıfırlarım. Kendi koşullu test mantığınıza ihtiyacınız olacak, ancak mülkün basit bir uygulaması:

    public bool JustRedirected
    {
        get
        {
            if (Session[RosadaConst.JUSTREDIRECTED] == null)
                return false;

            return (bool)Session[RosadaConst.JUSTREDIRECTED];
        }
        set
        {
            Session[RosadaConst.JUSTREDIRECTED] = value;
        }
    }

2

Ben benim iki sent atmak için gidiyorum. EĞER IIS sunucu tarafında erişebilir, o zaman protokol bağlamaları kullanımı ile HTTPS zorlayabilir. Örneğin, Blah adında bir web siteniz var . IIS'de iki site kuracaksınız : Blah ve Blah (Yönlendirme) . İçin Falan sadece yapılandırmak HTTPSbağlayıcı (ve FTPsen sıra güvenli bir bağlantı üzerinden zorlamak, emin olmak gerekirse). For Falan (Yönlendirme) sadece yapılandırmak HTTPbağlayıcı. Son olarak, Blah (Yönlendirme) için HTTP Yönlendirme bölümünde , tam hedef etkinken bir 301 yönlendirmesi ayarladığınızdan emin olun . IIS'deki her sitenin siteyi işaret ettiğinden emin olun.https://blah.comkendi kök klasörüne, aksi takdirde Web.config'inhepsi berbat olacak. Ayrıca HSTS, HTTPSed sitenizde, tarayıcının sonraki isteklerinin her zaman HTTPS'ye zorlanması ve yeniden yönlendirme yapılmaması için yapılandırdığınızdan emin olun .


2

Bu, @Troy Hunt'un temel aldığı daha kapsamlı bir cevaptır. Bu işlevi WebApplicationsınıfınıza şu dillerde ekleyin Global.asax.cs:

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
        // Allow https pages in debugging
        if (Request.IsLocal)
        {
            if (Request.Url.Scheme == "http")
            {
                int localSslPort = 44362; // Your local IIS port for HTTPS

                var path = "https://" + Request.Url.Host + ":" + localSslPort + Request.Url.PathAndQuery;

                Response.Status = "301 Moved Permanently";
                Response.AddHeader("Location", path);
            }
        }
        else
        {
            switch (Request.Url.Scheme)
            {
                case "https":
                    Response.AddHeader("Strict-Transport-Security", "max-age=31536000");
                    break;
                case "http":
                    var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery;
                    Response.Status = "301 Moved Permanently";
                    Response.AddHeader("Location", path);
                    break;
            }
        }
    }

(Yerel derlemenizde SSL'yi etkinleştirmek için projenin Özellikler bağlantısında etkinleştirin)


1

-> Basitçe, genel sınıf HomeController: Controller'ın üstüne [RequireHttps] ekleyin.

-> Ve GlobalFilters.Filters.Add (yeni RequireHttpsAttribute ()) ekleyin; Global.asax.cs dosyasındaki 'korumalı void Application_Start ()' yönteminde.

Tüm uygulamanızı HTTPS'ye zorlar.


Bunun WebForms kullanılarak sunulan sayfalar veya WebAPI ile oluşturulmuş API'lar için çalışacağına inanmıyorum. Yalnızca MVC denetleyicilerini kapsayacaktır.
Marc L.

1

Bazen mantıklı en iyi uygulamaları aramak için harcadım ve benim için mükemmel olan aşağıdakileri buldum. Umarım bu seni bir ara kurtarır.

Config dosyasını kullanma (örneğin bir asp.net web sitesi) https://blogs.msdn.microsoft.com/kaushal/2013/05/22/http-to-https-redirects-on-iis-7-x-and- daha yüksek/

veya kendi sunucunuzda https://www.sslshopper.com/iis7-redirect-http-to-https.html

[SHORT CEVAP] Basitçe Aşağıdaki kod içeri girer

<system.webServer> 
 <rewrite>
     <rules>
       <rule name="HTTP/S to HTTPS Redirect" enabled="true" 
           stopProcessing="true">
       <match url="(.*)" />
        <conditions logicalGrouping="MatchAny">
        <add input="{SERVER_PORT_SECURE}" pattern="^0$" />
       </conditions>
       <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" 
        redirectType="Permanent" />
        </rule>
       </rules>
 </rewrite>

1

IIS10'da (Windows 10 ve Server 2016), 1709 sürümünden itibaren, bir web sitesi için HSTS'yi etkinleştirmek için yeni, daha basit bir seçenek vardır.

Microsoft burada yeni yaklaşımın avantajlarını açıklıyor değişikliğin programlı olarak nasıl uygulanacağına veya ApplicationHost.config dosyasını doğrudan düzenleyerek (web.config gibi ancak bağımsız site düzeyi yerine IIS düzeyinde çalışır) birçok farklı örnek sunar ). ApplicationHost.config dosyası C: \ Windows \ System32 \ inetsrv \ config dizininde bulunabilir.

Bağlantı çürümesini önlemek için burada iki örnek yöntem özetledim.

Yöntem 1 - ApplicationHost.config dosyasını doğrudan düzenleme <site>Etiketler arasına bu satırı ekleyin:

<hsts enabled="true" max-age="31536000" includeSubDomains="true" redirectHttpToHttps="true" />

Yöntem 2 - Komut Satırı: Aşağıdakileri yükseltilmiş bir komut isteminden yürütün (örn. CMD'de sağ fare ve yönetici olarak çalıştır). Contoso'yu sitenizin adıyla IIS Yöneticisi'nde göründüğü gibi değiştirmeyi unutmayın.

c:
cd C:\WINDOWS\system32\inetsrv\
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.enabled:True" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.max-age:31536000" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.includeSubDomains:True" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.redirectHttpToHttps:True" /commit:apphost

Sınırlı erişiminiz olan bir barındırılan ortamda bulunuyorsanız, Microsoft'un bu makalelerde sunduğu diğer yöntemler daha iyi seçenekler olabilir.

IIS10 1709 sürümünün şimdi Windows 10'da bulunduğunu, ancak Windows Server 2016 için farklı bir sürümde olduğunu ve düzeltme eki veya hizmet paketi olarak yayımlanmayacağını unutmayın. 1709 hakkında ayrıntılar için buraya bakın .


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.