问题的根源
Token 操作不托管在控制器中,而是内置在较低级别的管道中的某个位置。对该机制的唯一访问是通过GrantResourceOwnerCredentials()
扩展类中的覆盖方法OAuthAuthorizationServerProvider
。(在我们的例子中是ApplicationOAuthProvider.cs
)。
GrantResourceOwnerCredentials()
确实有可用的上下文,但它不是作为 PreFlight 请求的一部分调用的,因此您无法为 CORS 插入适当的 PreFlight 响应标头。
解决方案
我们最终确定了以下解决方案。我不是它的忠实粉丝,因为它强制这些标题进入每个响应,但至少它有效。
解决方案是覆盖 Global.asax 中的 Application_PreSendRequestHeaders() 方法以插入适当的标头。
全球.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 条目:
网络配置
<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>
循环搜索有效来源的原因是您无法使用允许的来源列表进行响应...
这解决了大多数问题,但有一个例外(如果我没记错的话是 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 相关的有用链接