MVC 5 应用程序的 IIS 反向代理配置问题
IIS reverse proxy configuration issues with MVC 5 app
我无法在 IIS 8.5 中为我的 MVC5 应用程序正确配置反向代理。我们使用第 3 方应用程序 Tibco Spotfire WebPlayer 7.0.1 来集成到我们的 MVC webapp 中。为此,我们使用 Javascript API 从 WebPlayer 打开报告并将其插入到 iframe 中。
我们必须配置反向代理以允许请求转到安装了 WebPlayer 的后端服务器。我们的主要 webapp 位于 http://mywebapp.com/
,所有应该重写的请求看起来像 http://mywebapp.com/SpotfireWeb/...
,后端服务器位于私有 ip http://172.29.1.7/SpotfireWeb/...
我使用ARR 3.0和URL Rewrite Module 2.0配置反向代理的主要问题,但它不适用于*.ashx、*.aspx、*.axd, *.asmx 文件。看起来某些处理程序与 ARR/RewriteModule 冲突并且不允许将请求传递到不同的服务器
详情:
当我尝试加载像 http://mywebapp.com/SpotfireWeb/secret.html
这样的静态 html 文件时,请求被重写到 172.29.1.7
服务器,我得到了这个文件的内容。但是一旦我请求 http://mywebapp.com/SpotfireWeb/GetJavaScriptApi.ashx?Version=6.0
之类的东西,我就会从 mywebapp.com 收到 404
错误。我 运行 Wireshark 发现如果请求包含 *.ashx 文件,对后端服务器 172.29.1.7
的请求根本不会进行。
我安装了 Failed Requests Trace
并发现发生了事件 HANDLER_CHANGED
,将 ApplicationRequestRoutingHandler
更改为 System.Web.Mvc.MvcHandler
为了解决这个问题,我删除了一些处理程序,现在 Wireshark 捕获了对后端服务器的请求。我相信这种删除处理程序的方法是不正确的。可能是我以错误的方式配置了什么?
无论如何,当 POST 对 http://mywebapp.com/SpotfireWeb/AjaxService.asmx/InitiateOpen
的请求未处理时,我遇到了一个问题,我的初始应用程序出现 404 错误。当我删除 *.asmx 处理程序时,我仍然遇到同样的错误。这是我现在卡住的地方。
我的重写规则来自 mywebapp.com 的 web.config。我在网站级别配置它:
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" enabled="true" stopProcessing="true">
<match url="SpotfireWeb/?(.*)$" />
<action type="Rewrite" url="http://172.29.1.7/SpotfireWeb/{R:1}" logRewrittenUrl="true" />
<serverVariables>
<set name="ORIGINAL_HOST" value="{HTTP_HOST}" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<clear />
<rule name="ReverseProxyOutboundRule1" preCondition="" enabled="true">
<match filterByTags="A, Area, Base, Form, IFrame, Img, Input, Link, Script" pattern="SpotfireWeb/?(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true" />
<action type="Rewrite" value="http://mywebapp.com/SpotfireWeb/{R:1}" />
</rule>
<rule name="ReverseProxy_Redirection" preCondition="IsRedirection" enabled="true">
<match filterByTags="A, Area, Base, Form, IFrame, Img, Input, Link, Script" serverVariable="RESPONSE_Location" pattern="^http://[^/]+/(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{ORIGINAL_HOST}" pattern=".+" />
<add input="{URL}" pattern="^/(SpotfireWeb)/?.*" />
</conditions>
<action type="Rewrite" value="http://{ORIGINAL_HOST}/{C:1}/{R:1}" />
</rule>
<preConditions>
<preCondition name="IsRedirection">
<add input="{RESPONSE_STATUS}" pattern="3\d\d" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
有人见过类似的东西吗?
我认为根本原因在 MVC 处理程序中,但无法理解在哪里。
我解决了这个问题。显然我们不需要删除模块。答案基本上变成了failed requests的日志。
在 MAP_REQUEST_HANDLER 事件 ASP.NET 期间,基础架构确定当前请求的请求处理程序。在我的例子中,每次我请求 URL 时都选择了 MVC 处理程序,比如 /SpotfireWeb/...
,而不管 ARR 是当前处理程序。 Here 我发现:
..the handler mapping can be changed during request execution in the MAP_REQUEST_HANDLER event. This allows scenarios such as URL rewriting to work.
我的修复是从 MVC 路由中完全删除 SpotfireWeb
。因此,我将以下代码添加到 RouteConfig.cs
routes.IgnoreRoute("SpotfireWeb/{*pathInfo}");
整个 class 看起来像:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// ignore everything under 'SpotfireWeb' because this request will be routed
// to separate server via reverse proxy ARR/Rewrite module
routes.IgnoreRoute("SpotfireWeb/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { area = string.Empty, controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "GKSPortal.Controllers" });
}
}
我无法在 IIS 8.5 中为我的 MVC5 应用程序正确配置反向代理。我们使用第 3 方应用程序 Tibco Spotfire WebPlayer 7.0.1 来集成到我们的 MVC webapp 中。为此,我们使用 Javascript API 从 WebPlayer 打开报告并将其插入到 iframe 中。
我们必须配置反向代理以允许请求转到安装了 WebPlayer 的后端服务器。我们的主要 webapp 位于 http://mywebapp.com/
,所有应该重写的请求看起来像 http://mywebapp.com/SpotfireWeb/...
,后端服务器位于私有 ip http://172.29.1.7/SpotfireWeb/...
我使用ARR 3.0和URL Rewrite Module 2.0配置反向代理的主要问题,但它不适用于*.ashx、*.aspx、*.axd, *.asmx 文件。看起来某些处理程序与 ARR/RewriteModule 冲突并且不允许将请求传递到不同的服务器
详情:
当我尝试加载像 http://mywebapp.com/SpotfireWeb/secret.html
这样的静态 html 文件时,请求被重写到 172.29.1.7
服务器,我得到了这个文件的内容。但是一旦我请求 http://mywebapp.com/SpotfireWeb/GetJavaScriptApi.ashx?Version=6.0
之类的东西,我就会从 mywebapp.com 收到 404
错误。我 运行 Wireshark 发现如果请求包含 *.ashx 文件,对后端服务器 172.29.1.7
的请求根本不会进行。
我安装了 Failed Requests Trace
并发现发生了事件 HANDLER_CHANGED
,将 ApplicationRequestRoutingHandler
更改为 System.Web.Mvc.MvcHandler
为了解决这个问题,我删除了一些处理程序,现在 Wireshark 捕获了对后端服务器的请求。我相信这种删除处理程序的方法是不正确的。可能是我以错误的方式配置了什么?
无论如何,当 POST 对 http://mywebapp.com/SpotfireWeb/AjaxService.asmx/InitiateOpen
的请求未处理时,我遇到了一个问题,我的初始应用程序出现 404 错误。当我删除 *.asmx 处理程序时,我仍然遇到同样的错误。这是我现在卡住的地方。
我的重写规则来自 mywebapp.com 的 web.config。我在网站级别配置它:
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" enabled="true" stopProcessing="true">
<match url="SpotfireWeb/?(.*)$" />
<action type="Rewrite" url="http://172.29.1.7/SpotfireWeb/{R:1}" logRewrittenUrl="true" />
<serverVariables>
<set name="ORIGINAL_HOST" value="{HTTP_HOST}" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<clear />
<rule name="ReverseProxyOutboundRule1" preCondition="" enabled="true">
<match filterByTags="A, Area, Base, Form, IFrame, Img, Input, Link, Script" pattern="SpotfireWeb/?(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true" />
<action type="Rewrite" value="http://mywebapp.com/SpotfireWeb/{R:1}" />
</rule>
<rule name="ReverseProxy_Redirection" preCondition="IsRedirection" enabled="true">
<match filterByTags="A, Area, Base, Form, IFrame, Img, Input, Link, Script" serverVariable="RESPONSE_Location" pattern="^http://[^/]+/(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{ORIGINAL_HOST}" pattern=".+" />
<add input="{URL}" pattern="^/(SpotfireWeb)/?.*" />
</conditions>
<action type="Rewrite" value="http://{ORIGINAL_HOST}/{C:1}/{R:1}" />
</rule>
<preConditions>
<preCondition name="IsRedirection">
<add input="{RESPONSE_STATUS}" pattern="3\d\d" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
有人见过类似的东西吗? 我认为根本原因在 MVC 处理程序中,但无法理解在哪里。
我解决了这个问题。显然我们不需要删除模块。答案基本上变成了failed requests的日志。
在 MAP_REQUEST_HANDLER 事件 ASP.NET 期间,基础架构确定当前请求的请求处理程序。在我的例子中,每次我请求 URL 时都选择了 MVC 处理程序,比如 /SpotfireWeb/...
,而不管 ARR 是当前处理程序。 Here 我发现:
..the handler mapping can be changed during request execution in the MAP_REQUEST_HANDLER event. This allows scenarios such as URL rewriting to work.
我的修复是从 MVC 路由中完全删除 SpotfireWeb
。因此,我将以下代码添加到 RouteConfig.cs
routes.IgnoreRoute("SpotfireWeb/{*pathInfo}");
整个 class 看起来像:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// ignore everything under 'SpotfireWeb' because this request will be routed
// to separate server via reverse proxy ARR/Rewrite module
routes.IgnoreRoute("SpotfireWeb/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { area = string.Empty, controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "GKSPortal.Controllers" });
}
}