IT story

전체 사이트에 대해 https를 강제 실행하는 asp.net의 가장 좋은 방법은 무엇입니까?

hot-time 2020. 5. 18. 08:10
반응형

전체 사이트에 대해 https를 강제 실행하는 asp.net의 가장 좋은 방법은 무엇입니까?


약 6 개월 전에 나는 모든 요청이 https를 거쳐야하는 사이트를 시작했다. 페이지에 대한 모든 요청이 https를 통과했는지 확인할 수있는 유일한 방법은 페이지로드 이벤트에서 페이지를 확인하는 것입니다. 요청이 http가 아닌 경우 response.redirect ( " https://example.com ")

더 좋은 방법이 있습니까? 이상적으로 web.config의 일부 설정입니까?


HSTS를 사용하십시오

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

원래 답변 (2015 년 12 월 4 일 위의 내용으로 대체 됨)

원래

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 (또는 global.asax.vb)에 있습니다.

나는 web.config에서 그것을 지정하는 방법을 모른다


다른 방법 으로는 "Strict-Transport-Security"헤더를 브라우저에 반환하여 HSTS사용 하는 것입니다. 브라우저는이를 지원해야하며 (현재는 Chrome과 Firefox가 주로 사용함), 일단 설정되면 브라우저가 HTTP를 통해 사이트에 요청하지 않고 대신 요청을 HTTPS 요청으로 변환하여 발행합니다. . HTTP의 리디렉션과 함께 사용하십시오.

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를 인식하지 못하는 브라우저는 헤더를 무시하지만 switch 문에 의해 여전히 포착되어 HTTPS로 전송됩니다.


IIS7 모듈을 통해 리디렉션 할 수 있습니다.

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

ASP.NET MVC를 사용하는 경우 다음을 사용하여 두 가지 방법으로 전체 사이트에서 HTTPS를 통한 SSL / TLS를 강제 실행할 수 있습니다.

어려운 방법

1-글로벌 필터에 RequireHttpsAttribute를 추가하십시오.

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

2-위조 방지 토큰이 SSL / TLS를 사용하도록 강제 :

AntiForgeryConfig.RequireSsl = true;

3-Web.config 파일을 변경하여 쿠키가 기본적으로 HTTPS를 요구하도록 요구합니다.

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

4-NWebSec.Owin NuGet 패키지를 사용하고 다음 코드 줄을 추가하여 사이트 전체에서 Strict Transport Security를 ​​활성화하십시오. 아래에 사전로드 지시문을 추가하고 사이트를 HSTS 사전로드 사이트에 제출하십시오 . 여기여기에 더 많은 정보가 있습니다 . OWIN을 사용하지 않는 경우 NWebSec 사이트 에서 Web.config 메소드를 읽을 수 있습니다.

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

5-NWebSec.Owin NuGet 패키지를 사용하고 사이트 전체에서 HPKP (Public Key Pinning)를 활성화하려면 다음 코드 줄을 추가하십시오. 여기여기에 더 많은 정보가 있습니다 .

// 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-사용 된 URL에 https 체계를 포함시킵니다. 일부 브라우저에서 구성표를 모방하면 CSP (콘텐츠 보안 정책) HTTP 헤더 및 SRI (하위 리소스 무결성) 가 제대로 작동하지 않습니다. HTTPS에 대해 명시 적으로 작성하는 것이 좋습니다. 예 :

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

쉬운 길

사용 ASP.NET MVC 상용구 에서이 모든 훨씬 더 내장 된 프로젝트를 생성하려면 Visual Studio 프로젝트 템플릿을. 당신은 또한에 코드를 볼 수 있습니다 GitHub의 .


어떤 이유로 든 IIS에서 이것을 설정할 수 없다면 리디렉션을 수행하는 HTTP 모듈을 만들 것입니다.

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

그런 다음 DLL로 컴파일하고 프로젝트에 대한 참조로 추가하고 이것을 web.config에 배치하십시오.

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

당신이해야 할 일은 :

1) 아래와 같이 프로덕션 또는 스테이지 서버에 따라 web.config 내부에 키를 추가하십시오.

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

2) Inside your Global.asax file add below method.

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

If SSL support is not configurable in your site (ie. should be able to turn https on/off) - you can use the [RequireHttps] attribute on any controller / controller action you wish to secure.


It also depends on the brand of your balancer, for the web mux, you would need to look for http header X-WebMux-SSL-termination: true to figure that incoming traffic was ssl. details here: http://www.cainetworks.com/support/redirect2ssl.html


For @Joe above, "This is giving me a redirect loop. Before I added the code it worked fine. Any suggestions? – Joe Nov 8 '11 at 4:13"

This was happening to me as well and what I believe was happening is that there was a load balancer terminating the SSL request in front of the Web server. So, my Web site was always thinking the request was "http", even if the original browser requested it to be "https".

I admit this is a bit hacky, but what worked for me was to implement a "JustRedirected" property that I could leverage to figure out the person was already redirected once. So, I test for specific conditions that warrant the redirect and, if they are met, I set this property (value stored in session) prior to the redirection. Even if the http/https conditions for redirection are met the second time, I bypass the redirection logic and reset the "JustRedirected" session value to false. You'll need your own conditional test logic, but here's a simple implementation of the property:

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

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

I'm going to throw my two cents in. IF you have access to IIS server side, then you can force HTTPS by use of the protocol bindings. For example, you have a website called Blah. In IIS you'd setup two sites: Blah, and Blah (Redirect). For Blah only configure the HTTPS binding (and FTP if you need to, make sure to force it over a secure connection as well). For Blah (Redirect) only configure the HTTP binding. Lastly, in the HTTP Redirect section for Blah (Redirect) make sure to set a 301 redirect to https://blah.com, with exact destination enabled. Make sure that each site in IIS is pointing to it's own root folder otherwise the Web.config will get all screwed up. Also make sure to have HSTS configured on your HTTPSed site so that subsequent requests by the browser are always forced to HTTPS and no redirects occur.


This is a fuller answer based on @Troy Hunt's. Add this function to your WebApplication class in 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;
            }
        }
    }

(To enable SSL on your local build enable it in the Properties dock for the project)


-> Simply ADD [RequireHttps] on top of the public class HomeController : Controller.

-> And add GlobalFilters.Filters.Add(new RequireHttpsAttribute()); in 'protected void Application_Start()' method in Global.asax.cs file.

Which forces your entire application to HTTPS.


I spent sometime looking for best practice that make sense and found the following which worked perfected for me. I hope this will save you sometime.

Using Config file (for example an asp.net website) https://blogs.msdn.microsoft.com/kaushal/2013/05/22/http-to-https-redirects-on-iis-7-x-and-higher/

or on your own server https://www.sslshopper.com/iis7-redirect-http-to-https.html

[SHORT ANSWER] Simply The code below goes inside

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

If you are using ASP.NET Core you could try out the nuget package SaidOut.AspNetCore.HttpsWithStrictTransportSecurity.

Then you only need to add

app.UseHttpsWithHsts(HttpsMode.AllowedRedirectForGet, configureRoutes: routeAction);

This will also add HTTP StrictTransportSecurity header to all request made using https scheme.

Example code and documentation https://github.com/saidout/saidout-aspnetcore-httpswithstricttransportsecurity#example-code


In IIS10 (Windows 10 and Server 2016), from version 1709 onwards, there is a new, simpler option for enabling HSTS for a website.

Microsoft describe the advantages of the new approach here, and provide many different examples of how to implement the change programmatically or by directly editing the ApplicationHost.config file (which is like web.config but operates at the IIS level, rather than individual site level). ApplicationHost.config can be found in C:\Windows\System32\inetsrv\config.

I've outlined two of the example methods here to avoid link rot.

Method 1 - Edit the ApplicationHost.config file directly Between the <site> tags, add this line:

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

Method 2 - Command Line: Execute the following from an elevated command prompt (i.e. right mouse on CMD and run as administrator). Remember to swap Contoso with the name of your site as it appears in IIS Manager.

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

The other methods Microsoft offer in that articles might be better options if you are on a hosted environment where you have limited access.

Keep in mind that IIS10 version 1709 is available on Windows 10 now, but for Windows Server 2016 it is on a different release track, and won't be released as a patch or service pack. See here for details about 1709.

참고URL : https://stackoverflow.com/questions/47089/best-way-in-asp-net-to-force-https-for-an-entire-site

반응형