尝试将HTTP重定向到HTTPS(C#,IIS),但HTTPS在响应标头中转回HTTP - 重定向循环
本文关键字:重定向 HTTP HTTPS 响应 循环 IIS | 更新日期: 2023-09-27 18:34:57
我在同一台IIS服务器上设置了两个IIS网站。网站A包含大部分内容,这是用户在请求我们的地址(例如 www.websitea.com(时显示的内容。网站 B 是一个单独的项目,只包含整个内容的一部分,因此它是内部的(在 IIS 中绑定到 websiteb.com(,但通过 URL 重写,用户可以通过键入 www.websitea.com/websiteb 来访问它。
URL 重写在网站 A 的 web.config 中如下所示:
<rewrite>
<rules>
<clear />
<rule name="Website B rewrite rule" stopProcessing="true">
<match url="^websiteb(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{CACHE_URL}" pattern="^(https?)://" />
</conditions>
<action type="Rewrite" url="{C:1}://websiteb.com{R:1}" />
</rule>
</rules>
</rewrite>
{CACHE_URL} 和 {C:1} 位用于保持协议的使用。 例如,在HTTP上请求 www.websitea.com/websiteb/foo.html 的用户被"重写"为HTTP上的 websiteb.com/foo.html,而在HTTPS上 websitea.com/websiteb/bar.html 的请求被"重写"为在HTTPS上 websiteb.com/bar.html。
现在,对于某些网站B页面,我们希望用户仅使用HTTPS - 这是在我们的SomePageViewModel的ShouldBeHttps属性中设置的。因此,在 ActionFilterAttribute 中使用以下代码:
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.HttpContext.Request.IsSecureConnection)
return;
var result = filterContext.Result as ViewResult;
if (result != null)
{
if ((result.Model as SomePageViewModel).ShouldBeHttps)
{
HandleNonHttpsRequest(filterContext);
}
}
}
protected virtual void HandleNonHttpsRequest(ActionExecutedContext filterContext)
{
if (!string.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException("The method must be a GET");
string url = filterContext.HttpContext.Request.Url.ToString().Replace("http:", "https:");
filterContext.Result = new RedirectResult(url);
}
假设 www.websitea.com/websiteb/securepage.html 将在 ShouldBeHttps 属性中生成一个真正的值。
现在,当我通过转到 HTTP 上的 websiteb.com/securepage.html 直接在服务器上测试它时,我被正确重定向(状态代码 302(到 HTTPS 上的 websiteb.com/securepage.html。
我希望当我在HTTP上 www.websitea.com/websiteb/securepage.html 时,我将被重定向到HTTPS上的 www.websitea.com/websiteb/securepage.html。但是,我的浏览器最终进入重定向循环(ERR_TOO_MANY_REDIRECTS(。我可以在"文本视图"选项卡中的 Fiddler 中看到它似乎设置正确:
<html>
<head>
<title>Object moved</title>
</head>
<body>
<h2>Object moved to <a href="https://www.websitea.com/websiteb/securepage.html">here</a>.</h2>
</body>
</html>
但"标题"选项卡显示:
Response Headers
HTTP/1.1 302 Found
(...)
Transport
Location: http://www.websitea.com/websiteb/securepage.html
因此,它不是转到https,而是再次使用http,然后再次命中过滤器,依此类推。
我错过了什么吗?是一些 IIS 设置吗?
试试这个配置。适用于我的网站
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions><add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther" />
</rule>
这主要是 IIS 中的一个错误
1.禁用 URL 重写缓存
2.向规则添加"不安全"变量
3.清除缓存
最好的方法,如果您可以在不使用重写的情况下在代码中执行此操作
根据您使用的 IIS 版本,这可以修复您的错误:
x64
x86
KB2974666