2009-09-09 3 views
1

Это похоже на то, что это должна быть общая проблема, но я могу найти мало решений для нее.Ссылка на страницу https

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

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

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

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

+1

Я обновил свой ответ. –

ответ

0

Хорошо, я применил решение, которое переписывает относительные ссылки, если на странице 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); 
     } 
    } 
0

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

+0

Возможно, у вас может быть страница: 'leavessl.aspx?out = foopage', то вы можете изменить там протоколы (убедитесь, что данные, переданные параметру 'out', являются действительными страницами). –

+0

Странно, вы, кажется, удалили свой комментарий. Не стесняйтесь возвращать его; форматировщик просто испортил ваши ссылки, я понял, что вы имели в виду. –

+0

Определенно вариант, но перенаправление на каждую ссылку на странице ssl кажется мне очень тяжело. Я предпочел бы, чтобы ссылки были правильно отображены. Я думал, что это будет распространенная проблема. – Sheff

0

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

Обновление: Я нашел another question, где ответы дают более подробную информацию о плюсах и минусах этого подхода. Вот interesting link из этой темы.

+0

hmmmm. После вашего обновления я попытался подправить ваш ответ, и, поскольку я уже голосовал, он проголосовал. Теперь, если я попытаюсь проголосовать снова, он говорит, что голос слишком стар, чтобы его изменить. Кажется, немного, если есть проблема юзабилити. Извини за это. Что касается вашего ответа, я не уверен, что хочу пойти по маршруту перенаправления, но в любом случае полезен. – Sheff

0

Я склонен переопределить класс 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. Весь этот код из памяти, поэтому может быть flaky (я не могу вспомнить, если каталог приложения включен в RawUrl, например), но концепция существует.

+0

Проблема заключается в том, что он не охватывает ресурсы, отличные от страницы, такие как изображения или другие статические файлы. –

+0

Vinay: вы получите всплывающие окна безопасности, если у вас есть незащищенные образы, доступ к которым осуществляется с защищенной страницы. –

+0

Это был вариант, который я действительно рассматривал, просто пытаясь получить консенсус относительно наилучшей практики. Я волновался, что это было немного тяжело, как подход? – Sheff

1

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

Смежные вопросы