วิธีการบังคับใช้ HTTPS โดยใช้ไฟล์ web.config


220

ฉันค้นหารอบ ๆ Google และ StackOverflow พยายามหาวิธีแก้ปัญหานี้ แต่พวกเขาดูเหมือนจะเกี่ยวข้องกับ ASP.NET และอื่น ๆ

ฉันมักจะใช้ Linux บนเซิร์ฟเวอร์ของฉัน แต่สำหรับลูกค้ารายนี้ฉันใช้ Windows กับ IIS 7.5 (และ Plesk 10) นี่คือเหตุผลที่ฉันไม่คุ้นเคยกับ IIS และไฟล์web.configเล็กน้อย ใน.htaccessไฟล์คุณสามารถใช้เงื่อนไขการเขียนซ้ำเพื่อตรวจสอบว่าโปรโตคอลเป็น HTTPS และเปลี่ยนเส้นทางตามนั้นหรือไม่ มีวิธีง่ายๆในการทำสิ่งนี้โดยใช้ไฟล์ web.config หรือแม้กระทั่งใช้โมดูล' URL Rewrite ' ที่ฉันติดตั้งไว้หรือไม่

ฉันไม่มีประสบการณ์กับ ASP.NETดังนั้นหากเกี่ยวข้องกับการแก้ปัญหากรุณาระบุขั้นตอนการใช้งานให้ชัดเจน

เหตุผลที่ฉันทำสิ่งนี้กับ web.config ไม่ใช่ PHP คือฉันต้องการบังคับ HTTPS ในเนื้อหาทั้งหมดภายในไซต์


1
และสิ่งที่ตรงกันข้าม: stackoverflow.com/questions/25767014/ …
Chris Moschini

คำตอบ:


427

คุณต้องมีโมดูล URL Rewrite ควรเป็น v2 (ฉันไม่ได้ติดตั้ง v1 ดังนั้นจึงไม่สามารถรับประกันได้ว่ามันจะทำงานได้ที่นั่น แต่ควรจะ)

นี่คือตัวอย่างของ web.config ดังกล่าว - มันจะบังคับ HTTPS สำหรับทรัพยากรทั้งหมด (โดยใช้การเปลี่ยนเส้นทางถาวร 301)

<?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 โซลูชันเฉพาะนี้ไม่มีส่วนเกี่ยวข้องกับ ASP.NET/PHP หรือเทคโนโลยีอื่น ๆ เนื่องจากทำโดยใช้โมดูลการเขียน URL ใหม่เท่านั้น - จะถูกประมวลผลที่หนึ่งในระดับเริ่มต้น / ล่าง - ก่อนที่คำขอจะไปถึงจุดที่รหัสของคุณ ถูกประหารชีวิต


6
@BenCarey คุณควรดูStrict-Transport-Securityหัวข้อ: en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
LazyOne

22
ฉันขอแนะนำให้เปลี่ยนการเปลี่ยนเส้นทางเพื่อไม่ให้ผนวกสตริงการสืบค้นเนื่องจากมันเป็นส่วนหนึ่งของ {REQUEST_URI} แล้ว (ไม่เช่นนั้นพารามิเตอร์จะถูกเพิ่มสองครั้ง) <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
franzo

6
มันใช้งานได้ แต่น่าเสียดายที่ localhost เพื่อหลีกเลี่ยงปัญหานี้คุณสามารถเพิ่มสิ่งนี้ใน <conditions>: <add input = "{HTTP_HOST}" pattern = "localhost"
negate

5
ใช้ AWS Elastic beanstalk วิธีนี้ทำให้ฉันเปลี่ยนเส้นทางมากเกินไป 302 จนกระทั่งฉันแก้ไข: <match url=".*"/>เป็น<match url="http://*.*" />
Kevin R.

1
@Sam บางทีคุณอาจไม่ได้ติดตั้งโมดูล Rewrite URL? มันไม่ได้มาพร้อมกับ IIS โดยค่าเริ่มต้นจะต้องติดตั้งแยกต่างหาก เช่นdocs.microsoft.com/en-us/iis/extensions/url-rewrite-module/ …
LazyOne

80

สำหรับผู้ที่ใช้ ASP.NET MVC คุณสามารถใช้RequireHttpsAttributeเพื่อบังคับให้คำตอบทั้งหมดเป็น HTTPS:

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

สิ่งอื่น ๆ ที่คุณอาจต้องการทำเพื่อช่วยให้ไซต์ของคุณปลอดภัย:

  1. บังคับให้โทเค็นต่อต้านการปลอมแปลงเพื่อใช้ SSL / TLS:

    AntiForgeryConfig.RequireSsl = true;
  2. ต้องการคุกกี้เพื่อให้ใช้ HTTPS เป็นค่าเริ่มต้นโดยการเปลี่ยนไฟล์ Web.config:

    <system.web>
        <httpCookies httpOnlyCookies="true" requireSSL="true" />
    </system.web>
  3. ใช้NWebSec.Owinแพคเกจ NuGet และเพิ่มบรรทัดต่อไปนี้ของรหัสที่จะช่วยให้การรักษาความปลอดภัยที่เข้มงวดด้านการขนส่ง (HSTS) ผ่านเว็บไซต์ อย่าลืมที่จะเพิ่มคำสั่ง Preload ด้านล่างและส่งเว็บไซต์ของคุณไปยังเว็บไซต์ HSTS Preload ข้อมูลเพิ่มเติมที่นี่และที่นี่ โปรดทราบว่าหากคุณไม่ได้ใช้ OWIN จะมีวิธี Web.config ที่คุณสามารถอ่านบนเว็บไซต์NWebSec

    // app is your OWIN IAppBuilder app in Startup.cs
    app.UseHsts(options => options.MaxAge(days: 720).Preload());
  4. ใช้แพ็คเกจ NWebSec.Owin NuGet และเพิ่มบรรทัดของรหัสต่อไปนี้เพื่อเปิดใช้งานการปักหมุดกุญแจสาธารณะ (HPKP) ทั่วทั้งไซต์ ข้อมูลเพิ่มเติมที่นี่และที่นี่

    // 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. รวมถึงรูปแบบ https ใน URL ใด ๆ ที่ใช้ ส่วนหัว HTTP นโยบายความปลอดภัยเนื้อหา (CSP)และSubresource Integrity (SRI)เล่นได้ไม่ดีเมื่อคุณเลียนแบบโครงร่างในเบราว์เซอร์บางตัว เป็นการดีกว่าที่จะมีความชัดเจนเกี่ยวกับ HTTPS เช่น

    <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js">
    </script>
  6. ใช้เทมเพลตโครงการASP.NET MVC Boilerplate Visual Studio เพื่อสร้างโครงการที่มีทั้งหมดนี้และมีอยู่แล้วภายในอีกมากมายคุณยังสามารถดูรหัสบนGitHubได้


4
คำถามถาม ASP.NET แต่ไม่ได้ระบุ WebForms หรือ MVC ดังนั้นฉันจึงให้คำตอบที่ครอบคลุมสำหรับผู้ที่ใช้ MVC (ซึ่งไม่ได้ใช้ไฟล์ Web.config เพื่อบังคับ HTTPS) และยัง ... downvote
มูฮัมหมัดเรฮันซาอีด

6
a) การแก้ปัญหาทำงานได้ แต่สิ่งต่าง ๆ มีการเปลี่ยนแปลงคำถามที่โดดเด่นและมีอันดับสูงนี้ควรได้รับคำตอบที่อัพเดตโดยใช้สิ่งที่มีอยู่ใน MVC b) คำตอบพยายามที่จะครอบคลุมทุกฐาน คำถามนั้นไม่ง่ายการเปิดใช้ HTTPS ทั่วทั้งไซต์ต้องการมากกว่าการเปลี่ยนไฟล์ web.config ผู้อ่านอาจเข้าใจผิดคิดว่าการเปลี่ยนไฟล์ Web.config เป็นเรื่องที่ทำได้ ความปลอดภัยนั้นยากพอเพราะไม่มีคำตอบที่ไม่สมบูรณ์ / ล้าสมัย
Muhammad Rehan Saeed

11
ในความคิดของฉันนี่เป็นคำตอบที่ยอดเยี่ยมและมีคุณค่า เมื่อมีคน googles หัวข้อและตรงไปที่คำถามนี้ฉันดีใจที่คำตอบของคุณอยู่ที่นี่
ประธานาธิบดี James K. Polk

1
@MuhammadRehanSaeed โพสต์ที่ดี อาจเพิ่ม SRI ในรายการของคุณ? scotthelme.co.uk/subresource-integrity
Nathan

1
@MuhammadRehanSaeed จริง - ผมคิดว่าส่วนหัวของคุณ "สิ่งอื่น ๆ ที่คุณอาจต้องการที่จะทำอย่างไรที่จะช่วยรักษาความปลอดภัยเว็บไซต์ของคุณ" ทำให้ฉันคิดว่ามัน :)
นาธาน

14

หากต้องการเพิ่มคำตอบของ LazyOne ต่อไปนี้เป็นคำอธิบายในรุ่นที่มีคำอธิบายประกอบ

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

ล้างกฎอื่น ๆ ทั้งหมดที่อาจกำหนดไว้แล้วบนเซิร์ฟเวอร์นี้ สร้างกฎใหม่ที่เราจะตั้งชื่อ "เปลี่ยนเส้นทางคำขอทั้งหมดไปยัง https" หลังจากประมวลผลกฎนี้แล้วอย่าประมวลผลกฎอีกต่อไป! จับคู่ URL ที่เข้ามาทั้งหมด จากนั้นตรวจสอบว่าเงื่อนไขอื่น ๆ ทั้งหมดเหล่านี้เป็นจริงหรือไม่: ปิด HTTPS นั่นเป็นเพียงเงื่อนไขเดียว (แต่ต้องแน่ใจว่าเป็นจริง) หากเป็นเช่นนั้นส่งกลับเปลี่ยนเส้นทางถาวร 301 http://www.foobar.com/whatever?else=the#url-containsให้กับลูกค้าที่ อย่าเพิ่มสตริงข้อความค้นหาที่ท้ายเพราะจะเป็นการซ้ำสตริงข้อความค้นหา!

นี่คือความหมายของคุณสมบัติแอตทริบิวต์และค่าบางค่า

  • clearลบกฎเซิร์ฟเวอร์ทั้งหมดที่เราอาจสืบทอด
  • กฎกำหนดกฎ
    • ตั้งชื่อตามอำเภอใจ (แม้ว่าจะไม่ซ้ำกัน) สำหรับกฎ
    • หยุดการประมวลผลว่าจะส่งต่อการร้องขอทันทีไปยังไปป์ไลน์ที่ร้องขอ IIS หรือก่อนเพื่อประมวลผลกฎเพิ่มเติม
  • จับคู่เมื่อต้องการเรียกใช้กฎนี้
    • urlรูปแบบที่ใช้ประเมิน URL
  • เงื่อนไขเงื่อนไขเพิ่มเติมเกี่ยวกับเวลาที่จะเรียกใช้กฎนี้ เงื่อนไขจะดำเนินการเฉพาะเมื่อมีการแข่งขันนัดแรก
    • การจัดกลุ่มแบบลอจิคัลไม่ว่าเงื่อนไขทั้งหมดจะต้องเป็นจริง ( MatchAll) หรือเงื่อนไขใด ๆ จะต้องเป็นจริง ( MatchAny); คล้ายกับ AND vs OR
  • เพิ่มเพิ่มเงื่อนไขที่ต้องปฏิบัติตาม
    • อินพุตอินพุตที่เงื่อนไขกำลังประเมิน อินพุตอาจเป็นตัวแปรเซิร์ฟเวอร์
    • รูปแบบมาตรฐานที่จะประเมินอินพุต
    • เพิกเฉยกรณีที่การโอนเป็นทุนมีความสำคัญหรือไม่
  • การกระทำจะทำอย่างไรถ้าmatchและมันconditionsเป็นเรื่องจริง
    • ประเภทโดยทั่วไปสามารถเป็นredirect(ฝั่งไคลเอ็นต์) หรือrewrite(ฝั่งเซิร์ฟเวอร์)
    • urlสิ่งที่จะผลิตอันเป็นผลมาจากกฎนี้; ในกรณีนี้เชื่อมต่อhttps://กับตัวแปรเซิร์ฟเวอร์สองตัว
    • redirectTypeที่ HTTP redirect จะใช้; อันนี้เป็นแบบถาวร 301
    • appendQueryStringว่าจะเพิ่มสตริงแบบสอบถามที่ส่วนท้ายของผลลัพธ์urlหรือไม่ ในกรณีนี้เรากำลังตั้งค่าเป็นเท็จเพราะมี{REQUEST_URI}อยู่แล้ว

ตัวแปรเซิร์ฟเวอร์คือ

  • {HTTPS}ซึ่งเป็นทั้งหรือOFFON
  • {HTTP_HOST}เป็นwww.mysite.comและ
  • {REQUEST_URI} รวมถึงส่วนที่เหลือของ URI เช่น /home?key=value
    • เบราว์เซอร์จัดการ#fragment(ดูความคิดเห็นจาก LazyOne)

ดูเพิ่มเติมที่: https://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-configuration-reference


1
One note but: /home?key=value#fragmentเบราว์เซอร์ส่วนหนึ่งของ URL (จาก) ไม่ได้ถูกตั้งค่าไปยังเซิร์ฟเวอร์โดยเบราว์เซอร์ที่ต้องการใช้ภายในเครื่อง
LazyOne

@ LazyOne คำถาม เราใช้ web.config ด้านบนเพื่อเปลี่ยนเส้นทางจากgreenearth.game/about#fooเป็น HTTPS เรียบร้อยแล้ว การสลับไปใช้ HTTPS ประกอบด้วยส่วน #foo เนื่องจากส่วน #foo ไม่ได้ถูกส่งไปยังเซิร์ฟเวอร์การเปลี่ยนเส้นทางรวมอยู่ด้วยอย่างไร
Shaun Luttin

มันจัดการโดยเบราว์เซอร์ เพียงเปิดแท็บเครือข่ายใน Google Chrome (หรือคล้ายกันใน Firefox และอื่น ๆ ) และดูว่ามีการร้องขอ URL อะไรจริง ๆ (เช่นhttp://www.example.com/members#oopsคำขอจะถูกส่งไปhttp://www.example.com/membersที่ซึ่งจะถูกเปลี่ยนเส้นทางไปยังรุ่น HTTPS ที่https://www.example.com/members- เบราว์เซอร์ไม่เหลือ)
LazyOne

@ LazyOne ขอบคุณสำหรับสิ่งนั้น หากฉันจำได้ถูกต้องมีข้อบกพร่องบางอย่างของ WebKit ที่ป้องกันไม่ให้มีการรวมส่วนในการเปลี่ยนเส้นทาง ดังนั้นนี่จึงสมเหตุสมผล bugs.webkit.org/show_bug.cgi?id=24175
Shaun Luttin

1
en.wikipedia.org/wiki/Fragment_identifier - "ลูกค้าไม่ควรส่ง URI-fragments ไปยังเซิร์ฟเวอร์เมื่อพวกเขาดึงเอกสารและไม่มีความช่วยเหลือจากแอปพลิเคชันในเครื่อง (ดูด้านล่าง) ส่วนที่ไม่เข้าร่วมในการเปลี่ยนเส้นทาง HTTP" - เพื่อความชัดเจนในกรณีที่ฉันเข้าใจผิดความคิดเห็นล่าสุดของคุณ
LazyOne

6

คำตอบที่ยอมรับไม่ได้ผลสำหรับฉัน ฉันทำตามขั้นตอนในบล็อกนี้

จุดสำคัญที่ขาดหายไปสำหรับฉันก็คือฉันต้องดาวน์โหลดและติดตั้ง URL Rewrite Tool สำหรับ IIS ผมพบว่ามันนี่ ผลที่ได้คือ

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

1

ใน. Net Core ให้ทำตามคำแนะนำที่https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl

ใน startup.cs ของคุณให้เพิ่มสิ่งต่อไปนี้:

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

หากต้องการเปลี่ยนเส้นทาง Http เป็น Https ให้เพิ่มสิ่งต่อไปนี้ใน 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);

0

ไลบรารีNWebsec ที่ยอดเยี่ยมสามารถอัพเกรดคำขอของคุณจาก HTTP เป็น HTTPS โดยใช้upgrade-insecure-requestsแท็กภายในWeb.config:

<nwebsec>
  <httpHeaderSecurityModule>
    <securityHttpHeaders>
      <content-Security-Policy enabled="true">
        <upgrade-insecure-requests enabled="true"  />
      </content-Security-Policy>
    </securityHttpHeaders>
  </httpHeaderSecurityModule>
</nwebsec>

0

ฉันไม่ได้รับอนุญาตให้ติดตั้ง URL Rewrite ในสภาพแวดล้อมของฉันดังนั้นฉันพบเส้นทางใหม่

การเพิ่มสิ่งนี้ไปยัง web.config ของฉันเพิ่มข้อผิดพลาดในการเขียนซ้ำและทำงานบน 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>

จากนั้นทำตามคำแนะนำที่นี่: https://www.sslshopper.com/iis7-redirect-http-to-https.html

ฉันสร้างไฟล์ html ที่ทำการเปลี่ยนเส้นทาง (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>

ฉันหวังว่าบางคนจะพบว่าสิ่งนี้มีประโยชน์เพราะฉันไม่สามารถหาชิ้นส่วนทั้งหมดได้ในที่เดียวที่อื่น


-7

วิธีง่ายๆคือการบอก IIS เพื่อส่งไฟล์ข้อผิดพลาดของคุณเองสำหรับ HTTP ร้องขอ ไฟล์ดังกล่าวสามารถมีการเปลี่ยนเส้นทางเมตาการเปลี่ยนเส้นทาง JavaScript และคำแนะนำพร้อมลิงค์ ฯลฯ ... ที่สำคัญคุณยังสามารถตรวจสอบ "ต้องใช้ SSL" สำหรับเว็บไซต์ (หรือโฟลเดอร์) และสิ่งนี้จะใช้ได้

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

ทำไมการลงคะแนนคืออะไร มันใช้งานได้และตอบคำถาม
เปลี่ยนเส้นทาง

14
นี่คือการโหวตลงเพราะคุณกำลังบอก Google ว่าไม่พบไฟล์ของคุณแล้วคุณใช้ JavaScript เพื่อเปลี่ยนเส้นทางซึ่งโดยทั่วไปแล้วก็ไม่ดี
Thomas Bennett
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.