C# 从https页面链接

C# 从https页面链接,c#,.net,html,ssl,C#,.net,Html,Ssl,这听起来应该是一个常见的问题,但我能找到一些解决办法 基本上,https页面上的相对链接(通常在控件和母版页中找到)显然会以https的形式链接到非安全页面,这是不可取的 一种可能的解决方案是使用页面头部的base标记将所有相关PAT根指向http,但是安全页面中的任何相关资源都将根指向http,这也是不可取的 我考虑重写render方法,如果它是一个安全页面,那么将页面上的所有相关链接重写为http 应该怎么做?你是说所有绝对URL?答案是你不使用绝对URL。您使用相对的(/foo而不是htt

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

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

一种可能的解决方案是使用页面头部的base标记将所有相关PAT根指向http,但是安全页面中的任何相关资源都将根指向http,这也是不可取的

我考虑重写render方法,如果它是一个安全页面,那么将页面上的所有相关链接重写为http


应该怎么做?

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

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

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


更新:我发现答案提供了更多关于这种方法优缺点的细节。这是来自该线程的一个示例。

一种方法是实现一个
IHTTP模块
,该模块检查传入的请求,根据URL决定它们是否应位于
http:
https:
,如果请求使用的是“错误”协议,则发出重定向以使用“正确”协议


更新:我发现答案提供了更多关于这种方法优缺点的细节。这是来自该线程的一个示例。

我倾向于覆盖
System.Web.UI.Page
类,并添加
IsSecure
属性。然后,您可以在页面指令中设置:

<%@ Page Language="C#" MasterPageFile="~/Default.Master" AutoEventWireup="true" 
CodeBehind="Foo.aspx.cs" Inherits="Bar.Foo" IsSecure="true" %>
您的所有页面都需要从您自己的页面类继承,而不是从System.Web.UI中继承,但一旦排序完成,您就可以继续了


另外,所有这些代码都来自内存,因此可能很脆弱(例如,我永远记不起应用程序目录是否包含在
RawUrl
中),但概念就在那里。

我倾向于覆盖
System.Web.UI.Page
类并添加
IsSecure
属性。然后,您可以在页面指令中设置:

<%@ Page Language="C#" MasterPageFile="~/Default.Master" AutoEventWireup="true" 
CodeBehind="Foo.aspx.cs" Inherits="Bar.Foo" IsSecure="true" %>
您的所有页面都需要从您自己的页面类继承,而不是从System.Web.UI中继承,但一旦排序完成,您就可以继续了


另外,所有这些代码都来自内存,因此可能很脆弱(例如,我永远记不起应用程序目录是否包含在
RawUrl
中),但概念就在那里。

好的,我已经实现了一个解决方案,通过重写呈现方法重写ssl页面上的相对链接。我接受silky提出的观点,认为从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);
        }
    }

好的,我已经实现了一个解决方案,通过重写render方法重写ssl页面上的相对链接。我接受silky提出的观点,认为从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);
        }
    }

请记住存在与协议无关的绝对URL(例如
//example.com/images/artwork.jpg
)。如果当前的基本页面是https页面,则此类URL将是https URL。

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

也许您可以有一个页面:
leavessl.aspx?out=foopage
,然后您可以在那里更改协议(确保将传递给“out”参数的数据验证为有效页面)。奇怪的是,您似乎删除了您的注释。随时把它带回来;格式化程序把你的链接搞砸了,我明白你的意思。虽然这是一个挑战性的选项,但对ssl页面上的每个链接执行重定向对我来说似乎有点笨手笨脚。首先,我希望链接能够正确呈现。我想这是一个常见的问题。我试图在注释中添加上下文,格式化我添加的链接。我试图让它在注释中呈现一个文本字符串,而不是链接——我的错,是的。当然,这对性能也不好。他们的论点是,他们现在看到的任何东西都值得通过SSL进行保护。虽然事实并非如此。一位安全专业人士也会说,他们注册的页面的任何链接也需要使用SSL,否则你怎么能信任它?然后你得到了安全的DNS,这一切都崩溃了。总之:不要担心这样做。在认证后将其取出,“可能”就可以了。不过,您可以研究自己的意见。也许您可以有一个页面:
leavessl.aspx?out=foopage
,然后您可以在那里更改协议(确保将传递给“out”参数的数据验证为有效页面)。奇怪的是,您似乎删除了您的评论。随时把它带回来;格式化程序把你的链接搞砸了,我明白你的意思。虽然这是一个挑战性的选项,但对ssl页面上的每个链接执行重定向对我来说似乎有点笨手笨脚。首先,我希望链接能够正确呈现。我以为这会是一个常见的问题,所以我想