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


192

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

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


내 대답을 여기서 확인하십시오 stackoverflow.com/questions/33882350/…
Shady Sherif

답변:


250

제발 사용 HSTS (HTTP 엄격한 전송 보안)

에서 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에서 그것을 지정하는 방법을 모른다


7
이것은 작동하지만 위험합니다.이 코드를 실행하여 VS 2010에서 로컬로 실행하려고하면 시작 페이지가로드되지 않습니다. 대신 "이 웹 페이지를 사용할 수 없습니다"라는 메시지가 나타납니다. 수정하기 위해 URL에 "localhost"라는 문자열이 포함되어 있는지 테스트하는 두 번째 조건을 추가했습니다. 그렇지 않은 경우 https를 강제 실행하십시오.
mg1075

3
이것은 나에게 리디렉션 루프를주고있다. 코드를 추가하기 전에 정상적으로 작동했습니다. 어떤 제안?
Joe

9
이것이 유용한 보안을 제공하지는 않습니다. 실제로, 이미 안전한 사용자로부터의 연결 만 보호하고 공격중인 사용자를 보호하지 못합니다 (MITM은 단순히 리디렉션을 생략하고 모든 것을 "보안 된"사이트로 전달할 수 있기 때문입니다). IMHO, 사용자 에이전트 리디렉션은 기분이 좋은 부두 보안이며 때로는 위험한 안전 환상을 제공합니다. 갈 수있는 유일한 방법은 사용자 에이전트에게 보안 리소스 만 요청하도록 지시하고 그렇지 않은 경우 리디렉션하지 않는 것입니다. 이것이 HSTS가하는 일입니다. 아래 답변을보십시오.
tne

2
이 답변은 '유해한'것으로 간주되어 사용해서는 안됩니다. 위의 @tne의 의견에 따라.
Rosdi Kasim

2
@RosdiKasim이 답변이 12 월 4 '15 년 편집 이후에도 여전히 해로운 것으로 간주되어야합니까?
앤드류 모튼

123

다른 방법 으로는 "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로 전송됩니다.


6
이전에 HSTS 헤더에 대해 들어 본 적이 없지만 매우 멋져 보입니다. 작은 최대 연령 값 (5 분)을 사용해야하는 이유가 있습니까? 링크 된 Wikipedia 기사는 큰 값 (6-12 개월)으로 설정하도록 제안합니다.
dana

5
+1. 리디렉션 만 사용하여 보안을 저하시킬 수있는 이유에 대한 세부 정보가 포함 된 Troy의 블로그에서이 광범위한 기사를 확인하십시오. 힌트 : SSL 스트립 도구에 특히 취약합니다. troyhunt.com/2011/11/…
오란 데니슨

3
또한 NWebsec을 확인하는 것이 좋습니다 .이 기능은 매우 쉽습니다.
Tieson T.

16
if(!Request.IsLocal)디버깅을 중단하지 않도록 스위치를 감싸고 싶을 것 입니다.
저스틴 J 스타크

1
좋은 대답입니다. 하나의 미묘한 점-Http 헤더 ( "Strict-Transport-Security")의 경우 한 곳의 구성에 집중되는 대신 여러 가지 옵션이 있기 때문에 NWebSec과 같은 라이브러리를 사용하는 것이 좋습니다.
Ognyan Dimitrov

89

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>

12
또한 IIS 7.0의 경우 Url Rewrite Module 2.0
Chris

난 단지 동의하는 특정 페이지를 만드는이 링크 간단하고 도움을 발견 요청으로 https - support.microsoft.com/kb/239875
MANIK 아 로라

21

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를 ​​활성화하십시오. 아래에 Preload 지시문을 추가하고 HSTS Preload 사이트에 사이트를 제출하십시오. . 여기여기에 더 많은 정보가 있습니다 . 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의 .


3
<authentication mode="Forms"><forms requireSSL="true">
Pluto

1
@ muhammad-rehan-saeed mvc5 상용구를 사용하고 있지만 사이트가 프로덕션 서버에서 자동으로 https를 https로 리디렉션하지 않으므로 localhost에서만 누락 된 것이 있습니까?
Diin

이 질문에 대한 올바른 포럼이 아닙니다. GitHub 사이트에 이슈를 게시하십시오. 는 RequireHttpsAttribute리디렉션을 수행합니다. 당신이 가지고있는 한 괜찮습니다.
Muhammad Rehan Saeed

@MuhammadRehanSaeed, 당신의 대답을 사랑하십시오. 하지만 ... MakeCert로 만든 인증서의 SHA256 해시를 어떻게 얻습니까? 내가 가진 전부는 SHA-1 지문 일뿐입니다 ... 당신은 알고 있습니까?
Diana

1
@Diana 링크는 방법을 보여줄 수 있습니다.
Muhammad Rehan Saeed

13

어떤 이유로 든 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>

이것은 global.asax에 붙이는 것보다 더 관련이있는 것 같습니다. 궁금한 점이 있다면 이점이 있습니까?
Brian MacKay

1
이점은 사용하지 않으려면 web.config에서 모듈을 주석 처리하십시오. 이 솔루션 구성 가능하지만 다른 솔루션 구성 할 수 없습니다.
밥 Yexley

2
나는 약간 혼란 스럽다. 나는 무언가 같이 예상했던 app.BeginRequest += new OnBeginRequest;Init방법과는에 OnBeginRequest현재의 것을 포함 할 것이다 Init방법이 포함되어 있습니다. 이 모듈이 예상대로 작동합니까?
Jakub Šturc

작동하지 않습니다. OnBeginRequest 이벤트 등을 추가해야하며 작동합니다.
SnAzBaZ

이 잘못된 코드를 편집하지만 보안을 유지하려면 HSTS도 사용해야합니다. Troy Hunt의 답변으로 이동하여 모듈로 만드십시오. support.microsoft.com/en-us/kb/307996 (올디지만 좋은 제품)을 참조하십시오 .
Marc L.

4

당신이해야 할 일은 :

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

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

2) Global.asax 파일 내부에 아래 방법을 추가하십시오.

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

사이트에서 SSL 지원을 구성 할 수없는 경우 (즉, https를 켜거나 끌 수 있어야 함)-보호하려는 컨트롤러 / 컨트롤러 작업에서 [RequireHttps] 속성을 사용할 수 있습니다.



2

위의 @Joe의 경우 "이것은 리디렉션 루프를 제공합니다. 코드를 추가하기 전에 제대로 작동했습니다. 제안 사항이 있습니까? – Joe Nov 8 '11 at 4:13"

이것은 나에게도 일어나고 있었고 내가 믿었던 것은 웹 서버 앞에서 SSL 요청을 종료하는로드 밸런서가 있다는 것입니다. 따라서 제 웹 사이트는 원래 브라우저가 "https"를 요청하더라도 요청이 "http"라고 생각했습니다.

나는 이것이 약간 해 키라는 것을 인정하지만, 나를 위해 일한 것은 그 사람이 이미 한 번 리디렉션되었다는 것을 알기 위해 활용할 수있는 "JustRedirected"속성을 구현하는 것이 었습니다. 따라서 리디렉션이 필요한 특정 조건을 테스트하고 조건이 충족되면 리디렉션 전에이 속성 (세션에 저장된 값)을 설정합니다. 리디렉션에 대한 http / https 조건이 두 번째로 충족 되더라도 리디렉션 논리를 무시하고 "JustRedirected"세션 값을 false로 재설정합니다. 고유 한 조건부 테스트 로직이 필요하지만 속성의 간단한 구현은 다음과 같습니다.

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

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

2

나는 내 두 센트를 던질거야. 경우 는 IIS 서버 측에 액세스 할 수 있습니다, 당신은 프로토콜 바인딩을 사용하여 HTTPS를 강제 할 수 있습니다. 예를 들어 Blah 라는 웹 사이트가 있습니다. IIS에서는 BlahBlah (Redirect)의 두 사이트를 설정했습니다 . 들어 ㅋ는 단지 구성 HTTPS바인딩 (그리고 FTP당신이 아니라 보안 연결을 통해 강제로, 확인해야하는 경우)를. 들어 ㅋ (리디렉션)이 단지 구성 HTTP바인딩. 마지막으로 Blah (리디렉션)HTTP 리디렉션 섹션에서 를 하도록 301 리디렉션을 설정해야https://blah.com 정확한 대상이 활성화 . IIS의 각 사이트가 해당 사이트를 가리키는 지 확인하십시오.그렇지 않으면 루트 폴더를 소유하게 의 Web.config은 됩니다. 또한HSTS 브라우저의 후속 요청이 항상 HTTPS로 강제되고 리디렉션이 발생하지 않도록 HTTPS 사이트에 구성됩니다.


2

이것은 @Troy Hunt를 기반으로 한 완전한 답변입니다. 이 함수를 WebApplication클래스에 추가하십시오 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;
            }
        }
    }

(로컬 빌드에서 SSL을 활성화하려면 프로젝트의 속성 도크에서 SSL을 활성화하십시오)


1

-> Public 클래스 HomeController : Controller 위에 단순히 [RequireHttps]를 추가하십시오.

-> 그리고 GlobalFilters.Filters.Add (new RequireHttpsAttribute ())를 추가하십시오; Global.asax.cs 파일의 'protected void Application_Start ()'메서드에서

전체 애플리케이션을 HTTPS로 강제합니다.


WebForms 또는 WebAPI로 작성된 API를 사용하여 제공되는 모든 페이지에서 이것이 효과가 있다고 생각하지 않습니다. MVC 컨트롤러에만 적용됩니다.
Marc L.

1

나는 언젠가 이해가되는 모범 사례를 찾고 나에게 완벽한 다음을 발견했습니다. 이것이 당신을 언젠가 구할 수 있기를 바랍니다.

구성 파일 사용 (예 : asp.net 웹 사이트) https://blogs.msdn.microsoft.com/kaushal/2013/05/22/http-to-https-redirects-on-iis-7-x-and- 더 높은/

또는 자체 서버 https://www.sslshopper.com/iis7-redirect-http-to-https.html

[SHORT ANSWER] 간단히 아래 코드는

<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

IIS 10 (Windows 10 및 Server 2016)의 버전 1709부터는 웹 사이트에서 HSTS를 활성화하는 새롭고 더 간단한 옵션이 있습니다.

Microsoft는 여기에 새로운 접근 방식의 장점을 설명하고 프로그래밍 방식으로 변경을 구현하거나 ApplicationHost.config 파일 (web.config와 유사하지만 개별 사이트 수준이 아닌 IIS 수준에서 작동 함)을 직접 편집하여 변경 사항을 구현하는 방법에 대한 다양한 예를 제공합니다. ). ApplicationHost.config는 C : \ Windows \ System32 \ inetsrv \ config에 있습니다.

링크 부패를 피하기 위해 여기에 두 가지 예제 방법을 설명했습니다.

방법 1 -ApplicationHost.config 파일을 직접 편집하십시오. <site>태그 사이 에 다음 행을 추가하십시오.

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

방법 2- 명령 줄 : 관리자 권한 명령 프롬프트에서 다음을 실행하십시오 (예 : CMD에서 마우스 오른쪽 버튼을 클릭하고 관리자 권한으로 실행). IIS 관리자에 표시되는 사이트 이름으로 Contoso를 교체해야합니다.

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

액세스가 제한된 호스팅 환경에있는 경우 Microsoft가이 기사에서 제공하는 다른 방법이 더 나은 옵션 일 수 있습니다.

IIS10 버전 1709는 현재 Windows 10에서 사용할 수 있지만 Windows Server 2016의 경우 다른 릴리스 트랙에 있으며 패치 또는 서비스 팩으로 릴리스되지 않습니다. 1709에 대한 자세한 내용은 여기 를 참조 하십시오 .


0

ASP.NET Core를 사용하는 경우 Nuget 패키지 SaidOut.AspNetCore.HttpsWithStrictTransportSecurity를 ​​사용해 볼 수 있습니다.

그런 다음 추가하기 만하면됩니다

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

또한 https 체계를 사용하여 작성된 모든 요청에 ​​HTTP StrictTransportSecurity 헤더를 추가합니다.

예제 코드 및 설명서 https://github.com/saidout/saidout-aspnetcore-httpswithstricttransportsecurity#example-code

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.