Cara memaksa HTTPS menggunakan file web.config

220

Saya telah mencari di sekitar Google dan StackOverflow mencoba menemukan solusi untuk ini, tetapi mereka semua tampaknya berhubungan dengan ASP.NET dll.

Saya biasanya menjalankan Linux di server saya tetapi untuk klien yang satu ini saya menggunakan Windows dengan IIS 7.5 (dan Plesk 10). Ini menjadi alasan mengapa saya sedikit tidak terbiasa dengan file IIS dan web.config . Dalam .htaccessfile Anda dapat menggunakan kondisi penulisan ulang untuk mendeteksi apakah protokolnya adalah HTTPS dan mengarahkan ulang sesuai itu. Apakah ada cara sederhana untuk mencapai ini menggunakan file web.config, atau bahkan menggunakan modul ' URL Rewrite ' yang telah saya instal?

Saya tidak punya pengalaman dengan ASP.NET jadi jika ini terlibat dalam solusi maka harap sertakan langkah-langkah yang jelas tentang cara mengimplementasikan.

Alasan saya melakukan ini dengan web.config dan bukan PHP adalah karena saya ingin memaksakan HTTPS pada semua aset di dalam situs.

Ben Carey
sumber

Jawaban:

427

Anda memerlukan modul Penulisan Ulang URL, lebih disukai v2 (Saya belum menginstal v1, jadi tidak dapat menjamin bahwa itu akan berfungsi di sana, tetapi seharusnya).

Berikut adalah contoh web.config tersebut - ini akan memaksa HTTPS untuk SEMUA sumber daya (menggunakan 301 Permanent Redirect):

<?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 Solusi khusus ini tidak ada hubungannya dengan ASP.NET/PHP atau teknologi lainnya karena dilakukan hanya menggunakan modul penulisan ulang URL - diproses di salah satu level awal / bawah - sebelum permintaan sampai ke titik di mana kode Anda dieksekusi.

LazyOne
sumber
6
@BenCarey Anda juga harus melihat Strict-Transport-Securityheader: en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
LazyOne
22
Saya sarankan untuk mengubah arahan ulang sehingga tidak menambahkan string kueri karena sudah menjadi bagian dari {REQUEST_URI} (jika tidak, parameter dapat ditambahkan dua kali). <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
franzo
6
Ini berfungsi, tetapi sayangnya juga di localhost. Untuk menghindari ini, Anda dapat menambahkan ini ke <conditions>: <add input = "{HTTP_HOST}" pattern = "localhost" negate = "true" />
wezzix
5
Menggunakan AWS Elastic beanstalk, metode ini memberi saya 302 Terlalu banyak pengalihan sampai saya memodifikasi: <match url=".*"/>ke<match url="http://*.*" />
Kevin R.
1
@ Sam Mungkin Anda belum menginstal modul Penulisan Ulang URL? Itu tidak datang dengan IIS secara default, perlu diinstal secara terpisah. Contoh: docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/…
LazyOne
80

Bagi yang menggunakan ASP.NET MVC. Anda dapat menggunakan RequireHttpsAttribute untuk memaksa semua tanggapan menjadi HTTPS:

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

Hal-hal lain yang mungkin juga ingin Anda lakukan untuk membantu mengamankan situs Anda:

  1. Paksa token Anti-Pemalsuan untuk menggunakan SSL / TLS:

    AntiForgeryConfig.RequireSsl = true;
  2. Memerlukan Cookie untuk meminta HTTPS secara default dengan mengubah file Web.config:

    <system.web>
        <httpCookies httpOnlyCookies="true" requireSSL="true" />
    </system.web>
    
  3. Gunakan paket NWebSec.Owin NuGet dan tambahkan baris kode berikut untuk mengaktifkan Keamanan Transportasi Ketat (HSTS) di seluruh situs. Jangan lupa untuk menambahkan arahan Preload di bawah ini dan kirimkan situs Anda ke situs Preload HSTS . Informasi lebih lanjut di sini dan di sini . Perhatikan bahwa jika Anda tidak menggunakan OWIN, ada metode Web.config yang dapat Anda baca di situs NWebSec .

    // app is your OWIN IAppBuilder app in Startup.cs
    app.UseHsts(options => options.MaxAge(days: 720).Preload());
    
  4. Gunakan paket NWebSec.Owin NuGet dan tambahkan baris kode berikut untuk mengaktifkan Pinning Kunci Publik (HPKP) di seluruh situs. Informasi lebih lanjut di sini dan di sini .

    // 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. Sertakan skema https dalam URL apa pun yang digunakan. Kebijakan Keamanan Konten (CSP) HTTP header dan Subresource Integrity (SRI) tidak bermain bagus ketika Anda meniru skema di beberapa browser. Lebih baik secara eksplisit tentang HTTPS. misalnya

    <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js">
    </script>
    
  6. Gunakan template proyek ASP.NET MVC Boilerplate Visual Studio untuk menghasilkan proyek dengan semua ini dan banyak lagi yang sudah ada di dalamnya. Anda juga dapat melihat kode di GitHub .

Muhammad Rehan Saeed
sumber
4
Pertanyaannya menanyakan ASP.NET tetapi tidak menyatakan WebForms atau MVC, jadi saya memberikan jawaban yang komprehensif untuk mereka yang menggunakan MVC (Yang tidak menggunakan file Web.config untuk memaksa HTTPS) namun ... dibatalkan.
Muhammad Rehan Saeed
6
a) Solusinya berfungsi tetapi semuanya telah berubah, pertanyaan yang menonjol dan berperingkat tinggi ini layak mendapat jawaban yang diperbarui menggunakan apa yang ada di dalam MVC. b) Jawabannya mencoba untuk mencakup semua basis. Pertanyaannya tidak sederhana, mengaktifkan HTTPS di seluruh situs memerlukan lebih banyak daripada mengubah file web.config. Pembaca mungkin disesatkan untuk berpikir mengubah file Web.config adalah semua yang diperlukan. Keamanan cukup sulit karena tanpa jawaban yang tidak lengkap / ketinggalan jaman.
Muhammad Rehan Saeed
11
Menurut saya ini adalah jawaban yang sangat bagus dan berharga. Ketika seseorang menelusuri topik dan diarahkan ke pertanyaan ini, saya senang jawaban Anda ada di sini.
Presiden James K. Polk
1
@MuhammadRehanSaeed Kiriman bagus. Mungkin menambahkan SRI ke daftar Anda? scotthelme.co.uk/subresource-integrity
Nathan
1
@MuhammadRehanSaeed true - Saya kira judul Anda tentang "Hal-hal lain yang mungkin juga ingin Anda lakukan untuk membantu mengamankan situs Anda" membuat saya memikirkannya :)
Nathan
14

Untuk menambah jawaban LazyOne, berikut adalah versi jawabannya.

<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>

Hapus semua aturan lain yang mungkin sudah ditetapkan di server ini. Buat aturan baru, yang akan kami beri nama "Redirect semua permintaan ke https". Setelah memproses aturan ini, jangan memproses aturan lagi! Cocokkan semua URL yang masuk. Kemudian periksa apakah semua kondisi lain ini benar: HTTPS dimatikan. Yah, itu hanya satu syarat (tapi pastikan itu benar). Jika ya, kirim kembali pengalihan 301 Permanen ke klien di http://www.foobar.com/whatever?else=the#url-contains. Jangan tambahkan string kueri di akhir itu, karena itu akan menduplikasi string kueri!

Inilah yang dimaksud dengan properti, atribut, dan beberapa nilai.

  • hapus semua aturan server yang mungkin kita warisi.
  • aturan mendefinisikan aturan.
    • beri nama nama arbitrer (meskipun unik) untuk aturan tersebut.
    • stopProcessing apakah akan meneruskan permintaan segera ke pipa permintaan IIS atau pertama-tama memproses aturan tambahan.
  • cocokkan kapan harus menjalankan aturan ini.
    • url suatu pola untuk mengevaluasi URL
  • kondisi kondisi tambahan tentang kapan menjalankan aturan ini; ketentuan diproses hanya jika ada kecocokan pertama.
    • logicalGrouping apakah semua kondisi harus benar ( MatchAll) atau salah satu syarat harus benar ( MatchAny); mirip dengan AND vs OR.
  • add menambahkan kondisi yang harus dipenuhi.
    • masukan input yang sedang dievaluasi suatu kondisi; input dapat berupa variabel server.
    • pola standar yang digunakan untuk mengevaluasi input.
    • abaikanCase apakah kapitalisasi penting atau tidak.
  • tindakan apa yang harus dilakukan jika matchdan yang conditionssemua benar.
    • tipe umumnya dapat redirect(sisi klien) atau rewrite(sisi server).
    • url apa yang harus dihasilkan sebagai hasil dari aturan ini; dalam hal ini, menyatukan https://dengan dua variabel server.
    • redirectType HTTP redirect yang akan digunakan; ini adalah 301 Permanen.
    • appendQueryString apakah akan menambahkan string kueri di akhir hasil urlatau tidak; dalam hal ini, kami menetapkannya ke false, karena {REQUEST_URI}sudah termasuk itu.

Variabel server adalah

  • {HTTPS}yang bisa OFFatau ON.
  • {HTTP_HOST}adalah www.mysite.com, dan
  • {REQUEST_URI} termasuk sisa URI, mis /home?key=value
    • browser menangani #fragment(lihat komentar dari LazyOne).

Lihat juga: https://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-configuration-reference

Shaun Luttin
sumber
1
Satu catatan: fragmen bagian dari URL (dari /home?key=value#fragment) tidak disetel ke server oleh peramban karena dimaksudkan untuk digunakan secara lokal.
LazyOne
@LazyOne Pertanyaan. Kami berhasil menggunakan web.config di atas untuk mengalihkan dari greenearth.game/about#foo ke HTTPS. Beralih ke HTTPS mencakup fragmen #foo. Mengingat bahwa bagian #foo tidak dikirim ke server, bagaimana pengalihan menyertakannya?
Shaun Luttin
Ini ditangani oleh browser. Cukup buka tab jaringan di Google Chrome (atau yang serupa di Firefox, dll.) Dan lihat URL apa yang sebenarnya diminta (mis. http://www.example.com/members#oopsPermintaan akan dikirim http://www.example.com/membersyang kemudian diarahkan ke versi HTTPS di https://www.example.com/members- peramban sisanya)
LazyOne
@LazyOne Terima kasih untuk itu. Jika saya ingat dengan benar, ada beberapa bug WebKit yang mencegah fragmen agar tidak dimasukkan dalam arahan ulang. Jadi, ini masuk akal. bugs.webkit.org/show_bug.cgi?id=24175
Shaun Luttin
1
en.wikipedia.org/wiki/Fragment_identifier - "Klien tidak seharusnya mengirim fragmen URI ke server ketika mereka mengambil dokumen, dan tanpa bantuan dari aplikasi lokal (lihat di bawah) fragmen tidak berpartisipasi dalam pengalihan HTTP" - hanya untuk memperjelas kalau-kalau saya salah memahami komentar terakhir Anda.
LazyOne
6

Jawaban yang diterima tidak berhasil untuk saya. Saya mengikuti langkah-langkah di blog ini .

Poin kunci yang hilang bagi saya adalah bahwa saya perlu mengunduh dan menginstal Alat Penulisan Ulang URL untuk IIS. Saya menemukannya di sini . Hasilnya adalah sebagai berikut.

<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
sumber
1

Di .Net Core, ikuti instruksi di https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl

Di startup.cs Anda tambahkan yang berikut:

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

Untuk mengarahkan ulang Http ke Https, tambahkan berikut ini di 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);
Laki-laki yang luar biasa
sumber
0

Perpustakaan NWebsec yang sangat baik dapat meningkatkan permintaan Anda dari HTTP ke HTTPS menggunakan upgrade-insecure-requeststag -nya di dalam Web.config:

<nwebsec>
  <httpHeaderSecurityModule>
    <securityHttpHeaders>
      <content-Security-Policy enabled="true">
        <upgrade-insecure-requests enabled="true"  />
      </content-Security-Policy>
    </securityHttpHeaders>
  </httpHeaderSecurityModule>
</nwebsec>
Apa yang dia lakukan
sumber
0

Saya tidak diizinkan menginstal URL Menulis Ulang di lingkungan saya, jadi, saya menemukan jalur lain.

Menambahkan ini ke web.config saya menambahkan penulisan ulang kesalahan dan bekerja pada 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>

Kemudian, ikuti saran di sini: https://www.sslshopper.com/iis7-redirect-http-to-https.html

Saya membuat file html yang melakukan redirect (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>

Saya harap seseorang menemukan ini berguna karena saya tidak dapat menemukan semua bagian di satu tempat di tempat lain.

Spencer Sullivan
sumber
-7

Cara sederhana adalah memberi tahu IIS untuk mengirim file kesalahan khusus Anda untuk permintaan HTTP. File kemudian dapat berisi redirect meta, redirect JavaScript dan instruksi dengan tautan, dll. Yang penting, Anda masih dapat memeriksa "Memerlukan SSL" untuk situs (atau folder) dan ini akan berfungsi.

</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>
redirect
sumber
Mengapa downvote? Ini bekerja dan menjawab pertanyaan.
redirect
14
Ini adalah suara turun karena Anda memberi tahu Google bahwa file Anda tidak ditemukan dan kemudian Anda menggunakan JavaScript untuk mengarahkan ulang, yang biasanya hanya buruk.
Thomas Bennett