需要 SSL 但仍保留 asp.net 个自定义错误
Require SSL but still keep asp.net custom errors
我有 asp.net 个自定义错误,它们运行良好:
<customErrors mode="RemoteOnly" defaultRedirect="~/Error/Index/500">
<error statusCode="403" redirect="~/Error/Index/403" />
<error statusCode="404" redirect="~/Error/Index/404" />
<error statusCode="500" redirect="~/Error/Index/500" />
<error statusCode="502" redirect="~/Error/Index/502" />
<error statusCode="503" redirect="~/Error/Index/503" />
<error statusCode="504" redirect="~/Error/Index/504" />
</customErrors>
此外,ssl 证书已成功安装,我的站点可以通过 http 和 https 正常访问。
当我收到需要 SSL 的要求时,问题就出现了。该站点的 http link 已分发给 1000 个用户。所以我们需要将所有流向 http 地址的流量优雅地重定向到 https 主页。
我尝试使重定向正常工作的任何解决方案都会破坏自定义错误。
我有这个测试 url,它生成一个错误来测试我在 ~/error/test 的自定义错误页面。它使用 mvc 布局显示我的自定义错误页面。
无论我如何设置,一旦我在 IIS 的 SSL 设置中打开需要 SSL,如果我打开任何 http 自定义错误(以便启用 403.4 重定向),它甚至不会尝试显示我的自定义 500 页。它显示了通用的 http 500 页面。
我希望使用重定向在 http 级别处理 403.4,使用我的自定义错误页面在 asp.net 级别处理 500。顺便说一句,这不是一个页面,而是一个使用会话变量中的 .net 异常的控制器。
我怎样才能做到这一点?
问题似乎是 IIS "Requires SSL" 功能与现有链接之间的断开连接 - IIS 中的所有这一切导致它拒绝不是通过 HTTP 发出的请求,它不执行任何重定向。
403.4 是一个 custom IIS sub-status code,意思是 "SSL Required" - 如果您在没有 SSL 的情况下请求站点,您会收到该错误 - 即它会阻止所有不是在 HTTPS 下发出的请求。
发出的实际响应是标准的 403 - 禁止,不涉及重定向,也没有告诉浏览器它应该通过 SSL 请求站点的任何内容 - HTML 中的所有内容 returned,希望用户能够理解。在将请求传递给您的应用程序进行处理之前,IIS 发出了错误,这就是为什么您看不到任何自定义错误的原因 - 无论哪种方式,如果您看到错误页面,它仍然是 403 页面.
因此,如果您需要支持 HTTP 下的初始请求,则需要设置某种形式的重定向。
有几种方法可以做到这一点:
使用 UrlRewrite 模块 - 但请注意,这可能是一个单独的安装,具体取决于您的托管服务器。安装完成后,您可以执行以下操作:
<system.webServer>
<rewrite>
<rules>
<rule name="RequireSsl" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="ON" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
这将确保对服务器的所有请求(静态文件和 MVC 路由)都重定向到 SSL。
另一个选项是 [RequireHttps]
过滤器属性,它可以添加到控制器、操作或全局过滤器集合中,但是这主要只会影响 MVC 路由 - 静态文件仍然可以在没有 HTTPS 的情况下提供。
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
[...]
// Add RequireHttps to any existing filters to force all routes to SSL
filters.Add(new RequireHttpsAttribute());
}
请注意,这两者只会导致客户端对 GET 请求执行重定向,大多数客户端将忽略 POST 请求的 301/302,因为您不应该重新提交表单。
[RequireHttps]
选项只会为 GET 请求发出重定向,POST 请求将 return 无效操作异常:"Must Use HTTPS".
我有 asp.net 个自定义错误,它们运行良好:
<customErrors mode="RemoteOnly" defaultRedirect="~/Error/Index/500">
<error statusCode="403" redirect="~/Error/Index/403" />
<error statusCode="404" redirect="~/Error/Index/404" />
<error statusCode="500" redirect="~/Error/Index/500" />
<error statusCode="502" redirect="~/Error/Index/502" />
<error statusCode="503" redirect="~/Error/Index/503" />
<error statusCode="504" redirect="~/Error/Index/504" />
</customErrors>
此外,ssl 证书已成功安装,我的站点可以通过 http 和 https 正常访问。
当我收到需要 SSL 的要求时,问题就出现了。该站点的 http link 已分发给 1000 个用户。所以我们需要将所有流向 http 地址的流量优雅地重定向到 https 主页。
我尝试使重定向正常工作的任何解决方案都会破坏自定义错误。
我有这个测试 url,它生成一个错误来测试我在 ~/error/test 的自定义错误页面。它使用 mvc 布局显示我的自定义错误页面。
无论我如何设置,一旦我在 IIS 的 SSL 设置中打开需要 SSL,如果我打开任何 http 自定义错误(以便启用 403.4 重定向),它甚至不会尝试显示我的自定义 500 页。它显示了通用的 http 500 页面。
我希望使用重定向在 http 级别处理 403.4,使用我的自定义错误页面在 asp.net 级别处理 500。顺便说一句,这不是一个页面,而是一个使用会话变量中的 .net 异常的控制器。
我怎样才能做到这一点?
问题似乎是 IIS "Requires SSL" 功能与现有链接之间的断开连接 - IIS 中的所有这一切导致它拒绝不是通过 HTTP 发出的请求,它不执行任何重定向。
403.4 是一个 custom IIS sub-status code,意思是 "SSL Required" - 如果您在没有 SSL 的情况下请求站点,您会收到该错误 - 即它会阻止所有不是在 HTTPS 下发出的请求。
发出的实际响应是标准的 403 - 禁止,不涉及重定向,也没有告诉浏览器它应该通过 SSL 请求站点的任何内容 - HTML 中的所有内容 returned,希望用户能够理解。在将请求传递给您的应用程序进行处理之前,IIS 发出了错误,这就是为什么您看不到任何自定义错误的原因 - 无论哪种方式,如果您看到错误页面,它仍然是 403 页面.
因此,如果您需要支持 HTTP 下的初始请求,则需要设置某种形式的重定向。
有几种方法可以做到这一点:
使用 UrlRewrite 模块 - 但请注意,这可能是一个单独的安装,具体取决于您的托管服务器。安装完成后,您可以执行以下操作:
<system.webServer>
<rewrite>
<rules>
<rule name="RequireSsl" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="ON" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
这将确保对服务器的所有请求(静态文件和 MVC 路由)都重定向到 SSL。
另一个选项是 [RequireHttps]
过滤器属性,它可以添加到控制器、操作或全局过滤器集合中,但是这主要只会影响 MVC 路由 - 静态文件仍然可以在没有 HTTPS 的情况下提供。
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
[...]
// Add RequireHttps to any existing filters to force all routes to SSL
filters.Add(new RequireHttpsAttribute());
}
请注意,这两者只会导致客户端对 GET 请求执行重定向,大多数客户端将忽略 POST 请求的 301/302,因为您不应该重新提交表单。
[RequireHttps]
选项只会为 GET 请求发出重定向,POST 请求将 return 无效操作异常:"Must Use HTTPS".