Asp.net С# перенаправление с http на https - программирование
Подтвердить что ты не робот

Asp.net С# перенаправление с http на https

Итак, в моем коде я хочу определить, называется ли моя страница входа в систему http и перенаправляет ее на https.

Я знаю, что есть некодирующие способы скинуть эту кошку, но для разочарования технического анализа я поддерживаю это в коде.

            if (!Request.IsSecureConnection)
            {
                string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
                Response.Redirect(redirectUrl);
            }

Поэтому я бросаю это в свой Page_Load(...), убедитесь, что мой отладчик использует реальный IIS, а не VS2008s IIS, и ударил debug.

В отладчик, вальс, нажмите Response.Redirect( " https://localhost/StudentPortal3G/AccessControl/AdLogin.aspx" ), нажмите f5.

Получить "Internet Explorere Не удается отобразить веб-страницу, url - HTTP, а не HTTPS. Не получить информативную ошибку... то же самое не происходит в отладчике.

Так что мне не хватает? это, похоже, не наука о ракетах, я видел подобный код на многих блогах...

Что я делаю неправильно? Я полагаю, что это должна быть совершенно очевидная ошибка Rookie, но я этого не вижу.

4b9b3361

Ответ 1

Я бы сделал !Request.IsLocal, чтобы убедиться, что я не отлаживаю, хотя, если вы используете реальный экземпляр IIS с сертификатом, применяемым при отладке, это не должно быть проблемой.

if (!Request.IsLocal && !Request.IsSecureConnection)
{
    string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
    Response.Redirect(redirectUrl, false);
    HttpContext.ApplicationInstance.CompleteRequest();
}

Примечание. Этот ответ предполагает контекст MVC в контроллере, где HttpContext - свойство, содержащее текущий контекст. Если вам не повезло, что вы все еще используете WebForms или ссылаетесь на контекст дегенеративно, вам нужно будет использовать HttpContext.Current.ApplicationInstance.CompleteRequest().

Примечание. Я обновил это, чтобы он соответствовал рекомендуемому шаблону для завершения запроса в соответствии с документацией .

Когда вы используете этот метод в обработчике страницы, чтобы прервать запрос для одну страницу и начать новый запрос на другую страницу, установите endResponse на false, а затем вызовите метод CompleteRequest. Если вы укажете true для параметра endResponse этот метод вызывает метод End для исходный запрос, который генерирует исключение ThreadAbortException когда он завершится. Это исключение оказывает пагубное влияние на Интернет производительность приложения, поэтому пересылка false для Рекомендуется использовать параметр endResponse. Для получения дополнительной информации см. Метод конца.

Ответ 2

Я обычно вызываю следующее из OnPreInit в базовом классе, из которого все мои страницы наследуются. Конечно, вы могли бы просто сделать это на каждой странице... но вы не хотели бы этого делать сейчас?

Обратите внимание, что у меня есть два свойства для каждой страницы, поэтому я могу указать требование SSL для каждой страницы (RequiresSSL), в то время как я могу также переопределить и перенаправить проверку, если я хочу (с IgnoreRequiresSSL, что полезно для таких страниц, как ошибка страницы, на которые вы переписываете и не знаете, будут ли они зашифрованы или нет), но, конечно, вы можете удалить их для простых настроек.

    protected override void OnPreInit(EventArgs e)
    {
        base.OnPreInit(e);

        if (!IsPostBack)
            RedirectAccordingToRequiresSSL();

        ...
    }

    /// <summary>
    /// Redirect if necessary to ssl or non-ssl enabled URL dependant on RequiresSSL property setting.
    /// </summary>
    private void RedirectAccordingToRequiresSSL()
    {
        if (IgnoreRequiresSSL) return;

        if (RequiresSSL)
        {
            if (!Request.IsSecureConnection) // Need to redirect to https
                RedirectAccordingToRequiresSSL(Uri.UriSchemeHttps);
        }
        else if (Request.IsSecureConnection)
        {
            RedirectAccordingToRequiresSSL(Uri.UriSchemeHttp);
        }

        // Otherwise don't need to do any redirecting as already using the correct scheme
    }

    /// <summary>
    /// Redirect as requested to specified scheme
    /// </summary>
    /// <param name="scheme"></param>
    private void RedirectAccordingToRequiresSSL(string scheme)
    {
        var url = scheme + Uri.SchemeDelimiter + Request.Url.Authority + Request.Url.PathAndQuery;
        Response.Redirect(url, false);
    }

Ответ 3

На мой взгляд, лучший подход во всем мире.

Три причины.

  • Он работает как для MVC, так и Web API, как это делается на уровне IIS.
  • Это не влияет на локальные/отладочные настройки. (постоянное перенаправление может повредить вам при отладке сайтов https на вашем компьютере).
  • Использует постоянную переадресацию, поэтому все будущие запросы автоматически перейдут на https

Просто добавьте следующее в свой раздел <system.webServer> в свой "Web.config" для своего проекта.

 <system.webServer>
 ....

 <rewrite>
  <rules>
    <rule name="HTTP to HTTPS redirect" stopProcessing="true">
      <match url="(.*)" />
      <conditions>
        <add input="{HTTP_HOST}" pattern="localhost" negate="true" />
        <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>

Ответ 4

Вы также можете использовать новый UriBuilder:

Dim context As HttpContext = HttpContext.Current
If Not context.Request.IsSecureConnection Then
    Dim secureUrl As New UriBuilder(context.Request.Url)
    secureUrl.Scheme = "https"
    secureUrl.Port = 443
    context.Response.Redirect(secureUrl.ToString, False)
    Return
End If

С#

HttpContext context = HttpContext.Current;
if (!context.Request.IsSecureConnection)
{
    UriBuilder secureUrl = new UriBuilder(context.Request.Url);
    secureUrl.Scheme = "https";
    secureUrl.Port = 443;
    context.Response.Redirect(secureUrl.ToString(), false);
}

Ответ 5

Я также предлагаю решение tvalfonsso, но с небольшой модификацией, если у вас есть перерисовка URL (RawUrl отличается от Url)

    if (SPPage == SPPages.StartAutotrading && !Request.IsLocal && !Request.IsSecureConnection)
        {
            string redirectUrl = (Request.Url.ToString().Replace(Request.Url.PathAndQuery.ToString(), "") + Request.RawUrl).Replace("http:", "https:");
            Response.Redirect(redirectUrl);
        }

Ответ 6

отказ от ответственности - я был вовлечен в разработку этого проекта

Я бы рекомендовал использовать http://nuget.org/packages/SecurePages/ Он дает вам возможность защищать определенные страницы или использовать Regex для определения совпадений. Он также заставит все страницы не соответствовать Regex или напрямую указанному HTTP.

Вы можете установить его через NuGet: Install-Package SecurePages

Документы находятся здесь: https://github.com/webadvanced/Secure-Page-manager-for-asp.net#secure-pages

Простое использование:

SecurePagesConfiguration.Urls.AddUrl("/cart");

или

SecurePagesConfiguration.Urls.AddRegex(@"(.*)account", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);

Ответ 7

Здесь мое решение:

// Force HTTPS connection
if (!Request.IsSecureConnection)
{
    var uri = new Uri(Request.Url.ToString());
    var redirectUrl = Settings.CanonicalDomain + uri.PathAndQuery;
    Response.Status = "301 Moved Permanently";
    Response.AddHeader("Location", redirectUrl);
    Response.End();
}

Где Settings.CanonicalDomain - ваше имя хоста HTTPS. Это 301 перенаправление, которое может быть правильным ответом в некоторых случаях.

Ответ 8

В моей среде разработки мне нравится иметь отдельный каталог публикации с установленным IIS с самоподписанным сертификатом, который отличается от моей кодовой директории без сертификата, который я отлаживаю непосредственно внутри Visual Studio. В этом случае !Request.IsLocal не идеален, потому что он не работает нигде в вашей среде разработки, даже в каталоге IIS с сертификатом. Я предпочитаю это:

if (!IsPostBack && !HttpContext.Current.IsDebuggingEnabled) 
{
    // do http->https and https->http redirection here
}

HttpContext.Current.IsDebuggingEnabled основан на значении компиляции debug = "true/false" в вашем web.config. Я установил true в моем каталоге кода и false в моем каталоге публикации, когда мне нужно локально проверять перенаправление HTTP и https.

Я добавляю в IsPostBack просто, чтобы сделать его (немного) более эффективным, пропуская дополнительную проверку ssl, когда это не нужно.

Ответ 9

Одним из способов, которым я смог обеспечить перенаправление https, является следующее:

В пуле приложений у меня есть мое приложение, работающее только на порте 443, так что нет возможности для незашифрованного сеанса (если только схема шифрования не будет разбита на уязвимость..). Я создал другое приложение на порту 80 с тем же IP-адресом, который содержит только файл web.config со следующим кодом

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
    <httpRedirect enabled="true" destination="https://yourWebsiteURL.com" />
</system.webServer>