【问题标题】:IIS7 URL Rewriting: How not to drop HTTPS protocol from rewritten URL?IIS7 URL 重写:如何不从重写的 URL 中删除 HTTPS 协议?
【发布时间】:2011-02-06 05:31:17
【问题描述】:

我正在开发一个网站,该网站使用 IIS 7 的 URL 重写功能来执行从 example.com 到 www.example.com 的永久重定向,以及从类似的域名重写到“主”域名,例如从 www.examples.com 到 www.example.com。

这个重写规则 - 如下所示 - 已经有一段时间了。但是,我们最近添加了 HTTPS 支持,并注意到如果用户访问要重写为 www.example.com 的 URL 之一,则 HTTPS 将被丢弃。例如,如果用户访问https://example.com,他们会被重定向到http://www.example.com,而我们希望他们被发送到https://www.example.com

这是感兴趣的重写规则(在 Web.config 中):

<rule name="Canonical Host Name" stopProcessing="true">
    <match url="(.*)" />

    <conditions logicalGrouping="MatchAny">
        <add input="{HTTP_HOST}" pattern="^example\.com$" />
        <add input="{HTTP_HOST}" pattern="^(www\.)?example\.net$" />
        <add input="{HTTP_HOST}" pattern="^(www\.)?example\.info$" />
        <add input="{HTTP_HOST}" pattern="^(www\.)?examples\.com$" />
    </conditions>

    <action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>

如您所见,action 元素的 url 属性直接指向 http://,所以我明白为什么 https://example.com 会重定向到 http://www.example.com。我的问题是,我该如何解决这个问题?我尝试(天真地)从 url 属性中删除 http:// 部分,但这没有用。

【问题讨论】:

  • 看来只是将HTTP:// 留在重定向 URL 之外会导致 IIS 7.5 使用入站请求的协议。

标签: iis-7 url-rewriting


【解决方案1】:

在同事的帮助下找到了答案。

我需要使用多个带有 {HTTPS} 条件的规则。请注意以下规则中的 {HTTPS} 条件。

<rule name="Canonical Host Name (HTTP)" stopProcessing="true">
    <match url="(.*)" />

    <conditions logicalGrouping="MatchAny">
        <add input="{HTTPS}" pattern="OFF" />
        <add input="{HTTP_HOST}" pattern="^example\.com$" />
    </conditions>

    <action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>

<rule name="Canonical Host Name (HTTPS)" stopProcessing="true">
    <match url="(.*)" />

    <conditions logicalGrouping="MatchAny">
        <add input="{HTTPS}" pattern="ON" />
        <add input="{HTTP_HOST}" pattern="^example\.com$" />
    </conditions>

    <action type="Redirect" url="https://www.example.com/{R:1}" redirectType="Permanent" />
</rule>

然后我为备用域名重复上述规则对。

【讨论】:

  • 我相信你的意思是让那些人说“MatchAll”而不是“MatchAny”。否则你会陷入死循环,页面停止加载。
  • 第一条规则应该意味着“如果它的 HTTPS 模式关闭 AND HTTP_HOST url 看起来像这种模式”。第二条规则应该意味着“如果它的 HTTPS 模式关闭 AND HTTP_HOST url 看起来像这种模式”。
  • @Scott Mitchel 请你也写一些解释......对于模式中使用的符号?
【解决方案2】:

如果您只想根据当前使用的协议(根据您的上一个示例)进行重定向,那么有一个更简单的解决方案可以将您需要的规则数量减半。以下是我从一位同事那里学到的。

如您所见,{HTTPS} 参数将包含值 ON 或 OFF。您可以将此值映射到 https:// 或 http://,方法是将此值输入 rewritemap。

这是如何工作的:

1- 创建用于映射 {HTTPS} 值的 rewritemap 部分:

    <rewriteMap name="MapProtocol" defaultValue="OFF">
      <add key="ON" value="https://" />
      <add key="OFF" value="http://" />
    </rewriteMap>

由您决定是仅包含协议,还是包含分号和正斜杠。解决方案无关紧要,但无论您在哪里引用它,都要牢记在心。

2- 在任何需要的地方都可以参考这张地图。在此示例中,它用于出站规则,但也适用于您的场景:

    <rule name="Outbound-Rule Name" stopProcessing="true" preCondition="ResponseIsHtml">
      <match filterByTags="A, Link, Script" pattern="YOUR PATTERN" />
      <action type="Rewrite" value="{MapProtocol:{HTTPS}}{HTTP_HOST}/REST OF RELATIVE LINK HERE" />
    </rule>

就是这样,URL 重写模块现在应该自动为您的链接使用正确的协议,具体取决于您使用的是 https 还是 http。

希望这会有所帮助!

【讨论】:

  • 这肯定会改善 Scotts 的回答。我将结合您的两个答案进行第三次回复,以显示配置应该是什么样子。
【解决方案3】:

这是 Scott 对 Hasan 改进的回答。这应该涵盖混合的 SSL/非 SSL 站点。该规则基本上说“如果 url 没有 www.example.com”,则永久重定向到它。本质上...您正在将没有 www 或直接访问您的 IP 地址的人重定向到您的 IP 地址。

<rewrite>
<rules>
    <rule name="Canonical Host Name" stopProcessing="true">
        <match url="(.*)" />
        <conditions logicalGrouping="MatchAll">
            <add input="{HTTP_HOST}" pattern="^www\.example\.com$" negate="true" />
        </conditions>
        <action type="Redirect" url="{MapSSL:{HTTPS}}www.example.com/{R:1}" redirectType="Permanent" />
    </rule>
</rules>
<rewriteMaps>
    <rewriteMap name="MapSSL" defaultValue="http://">
        <add key="ON" value="https://" />
        <add key="OFF" value="http://" />
    </rewriteMap>
</rewriteMaps>
</rewrite>

【讨论】:

  • @Douglas defaultValue 属性指定默认输入参数,而不是返回值。在这种情况下,如果没有通过,则“OFF”是默认值。
  • @MattBorja:你确定吗? &lt;rewriteMap name="StaticRewrites" defaultValue=""&gt; "defaultValue 属性指定在映射中未定义传入 URL 时使用的值。在这种情况下,将返回一个空字符串。"
  • 刚刚做了一个测试确认,看起来它是默认的返回值,而不是我最初认为的输入参数。因此,在答案中,如果 {HTTPS} serverVariable 出于某种原因返回了除 ON 或 OFF 以外的任何内容(您可能永远不会看到发生这种情况...meh),它会写出 OFFwww.example.com
【解决方案4】:

这是一个跨域解决方案,不仅适用于example.com,还适用于任何域

<rewrite>
    <rules>
        <rule name="Canonical Host Name" stopProcessing="true">
            <match url="(.*)" />
            <conditions logicalGrouping="MatchAll">
                <add input="{HTTP_HOST}" pattern="^www\.([.a-zA-Z0-9]+)$" negate="true" />
            </conditions>
            <action type="Redirect" url="{MapProtocol:{HTTPS}}www.{HTTP_HOST}/{R:0}" redirectType="Permanent" />
        </rule>
    </rules>
    <rewriteMaps>
        <rewriteMap name="MapProtocol" defaultValue="OFF">
            <add key="ON" value="https://" />
            <add key="OFF" value="http://" />
        </rewriteMap>
    </rewriteMaps>
</rewrite>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 2011-04-07
    • 2011-07-30
    • 2023-03-17
    • 2012-02-07
    • 1970-01-01
    相关资源
    最近更新 更多