【问题标题】:Linking from a https page从 https 页面链接
【发布时间】:2009-09-09 11:45:56
【问题描述】:

这听起来应该是一个常见问题,但我找不到解决办法。

基本上,https 页面上的相对链接(通常在控件和母版页中找到)显然会链接到非安全页面作为 https,这是不可取的。

一种可能的解决方案是使用页面头部的基本标记将所有相关 pats 植根于 http,但随后安全页面中的任何相关资源都将植根于 http,这也是不可取的。

我考虑过覆盖渲染方法,如果它是安全页面,则将页面上的所有相关链接重写为 http。

应该怎么做?

【问题讨论】:

    标签: c# .net html ssl


    【解决方案1】:

    请记住存在独立于协议的绝对 URL(例如 //example.com/images/artwork.jpg)。如果当前基本页面是 https 页面,这样的 URL 将是 https URL。

    【讨论】:

      【解决方案2】:

      你的意思是所有的绝对网址?答案是您不使用绝对网址。您使用相对的(/foo 而不是 http://example.org/foo)。

      【讨论】:

      • 也许您可以有一个页面:leavessl.aspx?out=foopage,然后您可以在那里更改协议(确保将传递给“out”参数的数据验证为有效页面)。
      • 奇怪,你好像删除了你的评论。随意把它带回来;格式化程序只是弄乱了您的链接,我明白您的意思。
      • 绝对是一个选项,但对 ssl 页面上的每个链接执行重定向对我来说似乎有点沉重。我宁愿首先正确呈现链接。我认为这将是一个常见问题
      • 对不起,我试图添加上下文 ass 注释格式化了我添加的链接我试图让它呈现一个文字字符串而不是评论中的链接 - 我的错
      • 我愿意,是的。但这当然也对性能不利。争论是他们现在看到的任何东西都值得通过 SSL 保护。虽然它并没有那么真实。安全专家还会说他们注册的页面的任何链接也需要使用 SSL,否则你怎么能相信它呢?然后你得到保护 DNS,这一切都崩溃了。总结:不要担心这样做。在身份验证后将它们取出,这“可能”很好。不过,您可以研究自己的意见。
      【解决方案3】:

      一种方法是实现例如IHttpModule 检查传入的请求,从 URL 决定它们是否应该在 http:https: 上,如果请求使用“错误”协议,则发出重定向以使用“正确”协议。

      更新:我找到了another question,其中的答案提供了有关这种方法的优缺点的更多详细信息。这是来自该线程的interesting link

      【讨论】:

      • 嗯。在您更新后,我尝试支持您的答案,因为我已经投了反对票。现在,如果我再次尝试投票,它会说投票太旧而无法更改。如果那里存在 SO 可用性问题,似乎有点像。对于那个很抱歉。关于您的回答,我不确定我是否想走重定向路线,但无论如何都是有用的信息。
      【解决方案4】:

      好的,我已经实现了一个解决方案,如果在 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);
              }
          }
      

      【讨论】:

        【解决方案5】:

        我倾向于覆盖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 中的页面类,但一旦完成排序,您就可以开始使用了。

        附:所有这些代码都是从内存中提取的,因此可能很不稳定(例如,我不记得应用程序目录是否包含在 RawUrl 中)但概念就在那里。

        【讨论】:

        • 这样做的问题是它不涵盖非页面资源,例如图像或其他静态文件。
        • Vinay:如果您从安全页面访问了不安全的图像,您将收到安全弹出窗口。
        • 这是我实际上正在考虑的一个选项,只是试图就最佳实践达成共识。我担心这作为一种方法有点笨拙?
        • 确实,这是一种相当生硬的工具方法,但在我们的案例中,用户很少会在安全和非安全页面之间切换。 TBH 我很想知道人们还提出了哪些其他选择。
        • @silky:但问题是如何显示包含非 SSL 内容链接的 SSL 页面。您确实会收到警告,但大多数人在最初几次出现后将其关闭(因为有 很多 个网站会显示错误,否则)。
        猜你喜欢
        • 2013-04-21
        • 2014-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-31
        • 1970-01-01
        相关资源
        最近更新 更多