iis - IIS 中托管的 WebAPI 中的 CORS 问题

标签 iis asp.net-web-api cors preflight

我正在尝试实现一个应用程序,该应用程序使用与此 really awesome example 中演示的相同的基于 token 的身份验证机制Taiseer Joudeh 着。

在我的应用程序中,我不断遇到 Cors 问题。在某些配置中,我会在 POST 获取 token 的预检(OPTIONS)请求中收到 500 错误,或者我可以获取 token ,但随后在预检请求中收到 404 错误,以获取对实际 API 调用的 GET 请求不记名 token 。

一个区别是 Taiseer 的代码设置为托管在 IISExpress(或 Azure)中,而我的代码托管在本地 IIS 上(目前在 Windows 7 上运行)。

凭直觉,我尝试在本地 IIS 下托管他的 API,但我发现了完全相同的问题。 ( token 的预检请求出现 500 错误,看起来实际的 API 会正常工作)

从我读到的内容看来,这可能是 IIS 中的模块和处理程序与 WebApi 中的 Cors 实现之间存在一些冲突,但 Taiseer 的实现在托管在 Azure 中时有效,所以这可能是 IIS 版本的差异(我目前在 Windows 7 下运行)。

如何找出导致问题的原因?

最佳答案

问题的根源

token 操作不托管在 Controller 中,而是构建在较低级别管道的某个地方。对该机制的唯一访问是通过扩展 OAuthAuthorizationServerProvider 的类中的覆盖方法 GrantResourceOwnerCredentials()。 (在我们的例子中是 ApplicationOAuthProvider.cs)。

GrantResourceOwnerCredentials() 确实有可用的上下文,但它不会作为 PreFlight 请求的一部分被调用,因此您无法为 CORS 插入适当的 PreFlight 响应 header 。

解决方案

我们最终确定了以下解决方案。我不太喜欢它,因为它会强制将这些 header 放入每个响应中,但至少它有效。

解决方案是覆盖 Global.asax 中的 Application_PreSendRequestHeaders() 方法以插入适当的 header 。

全局.asax.cs

    void Application_PreSendRequestHeaders(Object sender, EventArgs e)
    {
        var origin = Request.Headers.Get("Origin");
        var validOrigins = ConfigurationManager.AppSettings["allowedCorsOrigins"].Split(',');
        if(validOrigins.Any(o => o == origin))
        {
            Response.Headers.Set("Access-Control-Allow-Origin", origin);
            Response.Headers.Set("Access-Control-Allow-Credentials", "true");
            Response.Headers.Set("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, withcredentials, Prefer");
            Response.Headers.Set("Access-Control-Expose-Headers", "Claims, *");
            Response.Headers.Set("Access-Control-Max-Age", "600");
            Response.Headers.Set("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
        }
    }

这需要以下 web.config 条目:

web.config

<configuration>
  <appSettings>
    <add key="allowedCorsOrigins" value="http://www.allowedsite1.net,http://localhost:22687" />
    <add key="allowedCorsMethods" value="get, post, put, delete, options, batch" />
    <add key="allowedCorsHeaders" value="*" />
  </appSettings>
...
</configuration>

循环搜索有效来源的原因是您无法使用允许的来源列表进行响应...

这解决了大部分问题,只有一个异常(exception)(如果我没记错的话是 PUT 和 DELETE 动词的问题)。这需要删除“ExtensionlessUrlHandler-Integrated-4.0”并在 web.config 的处理程序部分中重新添加路径和动词。

web.config(第二次更改)

<system.webServer>
    <handlers>
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="" />
    </handlers>
    ....
</system.webServer>

CORS相关的有用链接

关于iis - IIS 中托管的 WebAPI 中的 CORS 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36737538/

相关文章:

javascript - 跨源资源共享 (CORS) 问题

mysql - 是否可以将本地 MySQL 数据库复制到远程 MySQL 数据库?

iis - 将 ASP.NET 5 MVC 6 应用程序部署到 Linux 和 IIS 7

c# - 当API Controller 创建失败时,在MVC4中处理异常吗?

c# - ASP.Net:在 Page_Load 中调用异步方法

Spring CORS No 'Access-Control-Allow-Origin' header 存在

iis - 安装了 IIS,但出现空白页面,并且未显示在 Windows 服务列表中

java - Windows通过IIS Url重写在tomcat上单点登录

asp.net-web-api - webApi Controller 中的多个 GET 操作

javascript - 请求在服务器上成功,但在浏览器中导致 CORS 错误