Ссылка со страницы https

Похоже, это обычная проблема, но я могу найти небольшие решения.

В основном относительные ссылки на странице https (часто встречаются в элементах управления и главной странице), очевидно, будут ссылаться на незащищенные страницы как на https, что нежелательно.

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

Я подумал о переопределении метода рендеринга и, если это безопасная страница, переписать все относительные ссылки на странице как http.

Как это сделать?


person Sheff    schedule 09.09.2009    source источник


Ответы (5)


Помните о существовании абсолютных URL-адресов, не зависящих от протокола (например, //example.com/images/artwork.jpg). Такой URL-адрес будет URL-адресом https. IFF текущая базовая страница является страницей https.

person Brian    schedule 10.09.2009

Вы имеете в виду все абсолютные URL-адреса? Ответ: вы не используете абсолютные URL-адреса. Вы используете относительные (/foo вместо http://example.org/foo).

person Noon Silk    schedule 09.09.2009
comment
Возможно, у вас может быть страница: leavessl.aspx?out=foopage, тогда вы можете изменить там протоколы (убедитесь, что данные, переданные в параметр out, подтверждены как действительные страницы). - person Noon Silk; 09.09.2009
comment
Странно, похоже, вы удалили свой комментарий. Не стесняйтесь вернуть его; форматтер просто перепутал ваши ссылки, я понял, что вы имели в виду. - person Noon Silk; 09.09.2009
comment
Вызывающе вариант, но выполнение перенаправления для каждой ссылки на странице ssl кажется мне немного тяжелым. Я бы предпочел, чтобы ссылки отображались правильно. Я думал, это обычная проблема - person Sheff; 09.09.2009
comment
извините, я пытался добавить контекст, а комментарий отформатировал ссылки, которые я добавил, я пытался заставить его отображать их в виде буквальной строки, а не ссылки в комментарии - Моя плохая - person Sheff; 09.09.2009
comment
Но это не на каждой ссылке; это только первая ссылка для их передачи. ИМХО, я думаю, что оставлять SSL, когда попадаешь в него, не лучшая форма, но это уже другая история. - person Noon Silk; 09.09.2009
comment
Если вы не покидаете ssl, когда находитесь на странице ssl, как только пользователь посетит страницу ssl, он будет просматривать весь сайт в ssl по относительным ссылкам. Это будет иметь проблемы с производительностью, не так ли? Должен признаться, я не уверен, что лучше всего. Я понимаю вашу точку зрения о дурном тоне. Сохраняете ли вы пользователя в ssl после посещения ssl-страницы? - person Sheff; 09.09.2009
comment
Я знаю, да. Но и для производительности это, конечно же, плохо. Аргумент состоит в том, что все, что они сейчас видят, стоит защитить с помощью SSL. Хотя на самом деле это не так. Специалист по безопасности также скажет, что любая ссылка на страницу, на которую он подписался, также должна быть в SSL, иначе как вы можете ей доверять? Затем вы получаете безопасный DNS, и все разваливается. В итоге: не беспокойтесь об этом. Вытащите их после аутентификации, и это «вероятно» нормально. Однако вы можете изучить свое собственное мнение. - person Noon Silk; 09.09.2009

Один из способов - реализовать, например, IHttpModule, который проверяет входящие запросы, решает по URL-адресу, должны ли они быть на http: или https:, и, если запрос использует «неправильный» протокол, выдает перенаправление для использования «правильного» протокола.

Обновление: я нашел другой вопрос, где в ответах подробно рассказывается о плюсах и минусах такого подхода. Вот интересная ссылка из этой беседы.

person Vinay Sajip    schedule 09.09.2009
comment
хмммм. После вашего обновления я попытался проголосовать за ваш ответ и, поскольку я уже проголосовал, проголосовал против. Теперь, если я попытаюсь проголосовать снова, он скажет, что голосование слишком старое, чтобы его можно было изменить. Кажется, немного, если проблема с юзабилити ТАК есть. Извини за это. Что касается вашего ответа, я не уверен, что хочу пойти по маршруту перенаправления, но в любом случае это полезная информация. - person Sheff; 09.09.2009

Хорошо, я реализовал решение, которое перезаписывает относительные ссылки на ssl-странице путем переопределения метода рендеринга. Я считаю, что это дурной тон для перенаправления с ssl, но я также считаю, что использование ssl на страницах, которые не публикуют информацию о пользователях, является плохим тоном.

Мне все равно было бы интересно услышать, как другие решают эту проблему.

В любом случае вот мое решение. Я использую HtmlAgilityPack для анализа html, но вы можете использовать регулярное выражение, если хотите.

protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
        if (HttpContext.Current.Request.Url.Scheme == "https")
        {
            StringBuilder stringBuilder = new StringBuilder();
            HtmlTextWriter pageTextWriter = new HtmlTextWriter(new StringWriter(stringBuilder, System.Globalization.CultureInfo.InvariantCulture));
            base.Render(pageTextWriter);

            HtmlAgilityPack.HtmlDocument htmldoc = new HtmlAgilityPackHtmlDocument();
            htmldoc.LoadHtml(stringBuilder.ToString());
            HtmlAgilityPack.HtmlNodeCollection linkNodes = htmldoc.DocumentNode.SelectNodes("//a[@href]");
            if (linkNodes != null)
            {
                Uri baseUri = new Uri("http://www.mynonsslwebroot.co.uk/");
                foreach (HtmlAgilityPack.HtmlNode node in linkNodes)
                {
                    Uri uri;

                    if (Uri.TryCreate(baseUri, node.Attributes["href"].Value, out uri))
                    {
                        node.Attributes["href"].Value = uri.OriginalString;
                    }
                }
                writer.Write(htmldoc.DocumentNode.WriteTo());
            }
        }
        else
        {
            base.Render(writer);
        }
    }
person Sheff    schedule 09.09.2009

Я стараюсь переопределить класс System.Web.UI.Page и добавить атрибут IsSecure. Затем вы можете установить это в директиве Page:

<%@ Page Language="C#" MasterPageFile="~/Default.Master" AutoEventWireup="true" 
CodeBehind="Foo.aspx.cs" Inherits="Bar.Foo" IsSecure="true" %>

Затем в вашем собственном классе страницы вы можете переопределить OnPreInit, чтобы выполнить перенаправление, используя что-то вроде этого:

if (IsSecure && Request.Url.Scheme == "http")
{
    string targetUrl = String.Format(
                           "https://{0}{1}",
                           Request.Url.Host,
                           Request.RawUrl);
    Response.Redirect(targetUrl);
}
else if (!IsSecure && Request.Url.Scheme == "https")
{
    string targetUrl = String.Format(
                           "http://{0}{1}", 
                           Request.Url.Host, 
                           Request.RawUrl);
    Response.Redirect(targetUrl);
}

Все ваши страницы должны быть унаследованы от вашего собственного класса страницы, а не от класса System.Web.UI, но как только это будет отсортировано, все готово.

P.S. Весь этот код взят из памяти, поэтому может быть нестабильным (я никогда не могу вспомнить, включен ли каталог приложения в RawUrl, например), но концепция есть.

person Pike65    schedule 09.09.2009
comment
Проблема в том, что он не охватывает ресурсы, не относящиеся к странице, такие как изображения или другие статические файлы. - person Vinay Sajip; 09.09.2009
comment
Винай: Вы получите всплывающие окна безопасности, если у вас есть доступ к небезопасным изображениям с защищенной страницы. - person Noon Silk; 09.09.2009
comment
Это был вариант, который я на самом деле рассматривал, просто пытаясь прийти к консенсусу в отношении наилучшей практики. Я волновался, что этот подход был немного тяжелым? - person Sheff; 09.09.2009
comment
Это правда, что это довольно грубый инструментальный подход, но в нашем случае очень редко пользователь мог переключаться между защищенными и незащищенными страницами. ТБХ Мне любопытно посмотреть, какие еще варианты предлагают люди. - person Pike65; 09.09.2009
comment
@silky: Но вопрос в том, как показать SSL-страницу, содержащую ссылки на не-SSL-контент. Это правда, что вы получаете предупреждения, но большинство людей отключают их после первых нескольких появлений (поскольку в противном случае существует много сайтов, на которых отображается ошибка). - person Vinay Sajip; 09.09.2009
comment
Что ж, Request.IsSecureConnection не имеет прямого отношения к SSL. Если вы используете недействительные сертификаты SSL, это будет неверно. Лучшую надежность дает Request.ServerVariables [HTTPS] .ToLower () == on - person Marc Wittke; 10.09.2009
comment
Ах, я этого не знал. Отредактировано для использования вместо этого Request.Url.Scheme. - person Pike65; 10.09.2009