URL 重写模块 (IIS) 无法与 IIS 上托管的 OWIN 中间件一起使用
URL Rewrite Module (IIS) not working with OWIN Middleware hosted on IIS
如何将 URL 重写模块与 OWIN 中间件一起使用?
阅读 http://www.asp.net/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline 它说我应该能够使用 NuGet 包在 IIS 管道中使用 OWIN 中间件:
Microsoft.Owin.Host.SystemWeb
这是我尝试使用的代码:
Web.config:
<system.webServer>
<rewrite>
<rules>
<rule name="pandainserter" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*test.*" />
<conditions trackAllCaptures="true">
<add input="{REQUEST_URI}" pattern="/(.*?)/(.*)" />
</conditions>
<action type="Rewrite" url="http://{HTTP_HOST}:20000/v1/{C:2}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
</system.webServer>
Startup.cs (欧文):
[assembly: OwinStartup(typeof(ApiUrlRewriter.Startup))]
namespace ApiUrlRewriter
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Run(context =>
{
string t = DateTime.Now.Millisecond.ToString();
return context.Response.WriteAsync(t + " Production OWIN App");
});
}
}
}
我想做的是使用 OWIN 中间件,允许 CORS 并修复 OPTIONS 预检 http 调用(此处描述:How to make CORS Authentication in WebAPI 2?),同时仍然能够使用 IIS 重写模块,以将我的调用重写到同一服务器上的其他站点。
我在所有调用中都遇到了这个错误。将 OWIN 与 IIS 重写模块一起使用时:
HTTP Error 404.4 - Not Found
The resource you are looking for does not have a handler associated with it.
Detailed Error Information:
Module IIS Web Core
Notification MapRequestHandler
Handler ExtensionlessUrl-Integrated-4.0
Error Code 0x8007007b
似乎重写模块没有注册,我不确定我做错了什么,或者我是否使用了正确的方法?
首先,IIS URL Rewrite module 默认情况下似乎无法在 IIS Express 上运行(我没有尝试在本地开发机器上安装它)。
因此,当 运行 在 Windows Server 2012 上安装 IIS 和 IIS URL 重写模块时,我可以看到我的 HTTP(s) 请求开始被重写。
为了进一步参考,我发布了用于修复 CORS 预检问题的代码,同时还可以将 HTTP(s) 请求重写到其他服务器。请注意,这将允许来自任何来源的 CORS 请求。
Startup.cs class:
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(Startup))]
namespace ApiUrlRewriter
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use<CorsPreflightMiddlerware>();
app.Use<CorsAuthorizationMiddleware>();
}
}
}
CorsPreflightMiddlerware.cs class:
public class CorsPreflightMiddlerware : OwinMiddleware
{
private const string HTTP_METHOD_OPTIONS = "OPTIONS";
public CorsPreflightMiddlerware(OwinMiddleware next)
: base(next)
{
}
public async override Task Invoke(IOwinContext context)
{
IOwinRequest req = context.Request;
IOwinResponse res = context.Response;
if (req.Method == HTTP_METHOD_OPTIONS)
{
res.StatusCode = (int)HttpStatusCode.OK;
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, OPTIONS");
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Headers", "Content-Type, Authorization");
}
else
{
await Next.Invoke(context);
}
}
}
CorsAuthorizationMiddleware.cs class:
public class CorsAuthorizationMiddleware : OwinMiddleware
{
public CorsAuthorizationMiddleware(OwinMiddleware next)
: base(next)
{
}
public async override Task Invoke(IOwinContext context)
{
IOwinRequest req = context.Request;
IOwinResponse res = context.Response;
var origin = req.Headers.Get("Origin");
if (!string.IsNullOrEmpty(origin))
{
res.Headers.Set("Access-Control-Allow-Origin", origin);
}
if (string.IsNullOrEmpty(res.Headers.Get("Access-Control-Allow-Credentials")))
{
res.Headers.Set("Access-Control-Allow-Credentials", "true");
}
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, OPTIONS");
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Headers", "Content-Type, Authorization");
await Next.Invoke(context);
}
}
Web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<rewrite>
<rules>
<rule name="test" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*test.*" />
<conditions trackAllCaptures="true">
<add input="{REQUEST_URI}" pattern="/(.*?)/(.*)" />
</conditions>
<action type="Rewrite" url="http://{HTTP_HOST}:20000/v1/{C:2}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
如何将 URL 重写模块与 OWIN 中间件一起使用?
阅读 http://www.asp.net/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline 它说我应该能够使用 NuGet 包在 IIS 管道中使用 OWIN 中间件:
Microsoft.Owin.Host.SystemWeb
这是我尝试使用的代码:
Web.config:
<system.webServer>
<rewrite>
<rules>
<rule name="pandainserter" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*test.*" />
<conditions trackAllCaptures="true">
<add input="{REQUEST_URI}" pattern="/(.*?)/(.*)" />
</conditions>
<action type="Rewrite" url="http://{HTTP_HOST}:20000/v1/{C:2}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
</system.webServer>
Startup.cs (欧文):
[assembly: OwinStartup(typeof(ApiUrlRewriter.Startup))]
namespace ApiUrlRewriter
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Run(context =>
{
string t = DateTime.Now.Millisecond.ToString();
return context.Response.WriteAsync(t + " Production OWIN App");
});
}
}
}
我想做的是使用 OWIN 中间件,允许 CORS 并修复 OPTIONS 预检 http 调用(此处描述:How to make CORS Authentication in WebAPI 2?),同时仍然能够使用 IIS 重写模块,以将我的调用重写到同一服务器上的其他站点。
我在所有调用中都遇到了这个错误。将 OWIN 与 IIS 重写模块一起使用时:
HTTP Error 404.4 - Not Found The resource you are looking for does not have a handler associated with it.
Detailed Error Information:
Module IIS Web Core
Notification MapRequestHandler
Handler ExtensionlessUrl-Integrated-4.0
Error Code 0x8007007b
似乎重写模块没有注册,我不确定我做错了什么,或者我是否使用了正确的方法?
首先,IIS URL Rewrite module 默认情况下似乎无法在 IIS Express 上运行(我没有尝试在本地开发机器上安装它)。
因此,当 运行 在 Windows Server 2012 上安装 IIS 和 IIS URL 重写模块时,我可以看到我的 HTTP(s) 请求开始被重写。
为了进一步参考,我发布了用于修复 CORS 预检问题的代码,同时还可以将 HTTP(s) 请求重写到其他服务器。请注意,这将允许来自任何来源的 CORS 请求。
Startup.cs class:
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(Startup))]
namespace ApiUrlRewriter
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use<CorsPreflightMiddlerware>();
app.Use<CorsAuthorizationMiddleware>();
}
}
}
CorsPreflightMiddlerware.cs class:
public class CorsPreflightMiddlerware : OwinMiddleware
{
private const string HTTP_METHOD_OPTIONS = "OPTIONS";
public CorsPreflightMiddlerware(OwinMiddleware next)
: base(next)
{
}
public async override Task Invoke(IOwinContext context)
{
IOwinRequest req = context.Request;
IOwinResponse res = context.Response;
if (req.Method == HTTP_METHOD_OPTIONS)
{
res.StatusCode = (int)HttpStatusCode.OK;
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, OPTIONS");
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Headers", "Content-Type, Authorization");
}
else
{
await Next.Invoke(context);
}
}
}
CorsAuthorizationMiddleware.cs class:
public class CorsAuthorizationMiddleware : OwinMiddleware
{
public CorsAuthorizationMiddleware(OwinMiddleware next)
: base(next)
{
}
public async override Task Invoke(IOwinContext context)
{
IOwinRequest req = context.Request;
IOwinResponse res = context.Response;
var origin = req.Headers.Get("Origin");
if (!string.IsNullOrEmpty(origin))
{
res.Headers.Set("Access-Control-Allow-Origin", origin);
}
if (string.IsNullOrEmpty(res.Headers.Get("Access-Control-Allow-Credentials")))
{
res.Headers.Set("Access-Control-Allow-Credentials", "true");
}
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, OPTIONS");
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Headers", "Content-Type, Authorization");
await Next.Invoke(context);
}
}
Web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<rewrite>
<rules>
<rule name="test" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*test.*" />
<conditions trackAllCaptures="true">
<add input="{REQUEST_URI}" pattern="/(.*?)/(.*)" />
</conditions>
<action type="Rewrite" url="http://{HTTP_HOST}:20000/v1/{C:2}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>