我正在尝试实现一个应用程序,该应用程序使用与此 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/