WCF REST服务中的CORS支持
本文关键字:CORS 支持 REST 服务 WCF | 更新日期: 2023-09-27 18:07:02
我有一个WCF REST服务托管在一个Windows服务,我想发送访问-控制-允许-起源HTTP头(定义为CORS的一部分)与每个响应。
我尝试的解决方案是在IDispatchMessageInspector实现中有以下内容:
public void BeforeSendReply(ref Message reply, object correlationState)
{
var httpResponse = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
if (httpResponse != null)
{
// test of CORS
httpResponse.Headers["Access-Control-Allow-Origin"] = "*";
}
}
正常情况下,这是可行的,但不幸的是,我的服务也使用HTTP基本授权,这意味着当没有授权头的请求进入时,WCF会自动发送401响应请求凭据。不幸的是,WCF不会在初始交换期间调用我的IDispatchMessageInspector,因此Access-Control-Allow-Origin头不会添加到初始交换中。
当我尝试从浏览器调用服务时,出现了这个问题。CORS指定,只有当源域与Access-Control-Allow-Origin响应头中列出的域匹配(*匹配所有域)时,才允许跨域请求。不幸的是,当浏览器看到没有access - control - allow - origin头的初始401响应时,它会阻止访问(根据同源策略)。
是否有任何方法添加一个头到初始401响应自动发送的WCF?
这家伙救了我的命。
http://blogs.microsoft.co.il/blogs/idof/archive/2011/07.aspx我打算把他的一些笔记放在这里,以防有一天那个网页死了。(我讨厌找到"你的答案就在这里"的链接,然后这个链接就死了。)
<behaviors>
<endpointBehaviors>
<behavior name="webSupport">
<webHttp />
<CorsSupport />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="CorsSupport" type="WebHttpCors.CorsSupportBehaviorElement, WebHttpCors, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<services>
<service name="Service.JSonService">
<endpoint address="http://localhost:8080" behaviorConfiguration="webSupport” binding="webHttpBinding" contract="Service.IJSonService" />
</service>
</services>
现在,你必须找到他的可下载库"WebHttpCors.dll"。
但有足够的(上面)帮助你谷歌/bing你的方式解决问题。
让我大吃一惊的部分(在我的场景中)是IE可以工作,但是Firefox不能工作。
我的原始页面是:
http://localhost:53692/test/WCFCallTestViaJQ14.htm
所以我的服务在:
http://localhost:8002/MyWCFService/MyWCFMethodByWebGet?state=NC&city=Raleigh
所以我有localhost <<->> localhost流量
****但是端口是不同的。(53692和8002)****
IE对此没有意见。
然后你要记住,每个浏览器处理他们的。send()请求是不同的(在JQUERY内部)。
现在一切都说得通了。
//JavaScript snipplet from JQuery library
if (window.XMLHttpRequest) {
returnObject = new XMLHttpRequest();
} else if (window.ActiveXObject) {
returnObject = new ActiveXObject("Microsoft.XMLHTTP");
} else {
msg = "Your browser doesn't support AJAX!";
}
这里有一些关键词,短语,我一直在谷歌上搜索,最终带我到某个地方。
Result: [Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIXMLHttpRequest.statusText]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: http://localhost:53692/test/WCFCallTestViaJQ14.htm :: HandleJQueryError :: line 326" data: no]
XMLHttpRequest Send "NS_ERROR_FAILURE"
JQuery Ajax WCF Self Hosted CORS JSON
现在,你需要阅读他的博客来理解代码是做什么的:
例如,他说:
" Access-Control-Allow-Origin "报头,值为" * "
这可能是你想要的,也可能不是。您可能希望更好地控制这个值(头)和其他值(方法和起源)。
开发环境是一回事。(使用所有你想要的*)。
生产是另一回事,你可能想要将这些*值调整为更具歧视性的值。简而言之,您需要了解CORS在安全性方面实际上为您做了什么,而不仅仅是添加一个允许所有内容进入的行为。
allowed-origins: '*'
allowed-headers: '*'
allowed-methods: '*'
要实现你想要的,你需要自己处理授权,这是可能的通过实现+注册一个HttpModule…在那里,你可以发出401,以及任何你想要的HTTP头…这里甚至有一个示例实现——参见向WCF REST服务添加基本的HTTP授权
编辑-从OP评论后:
由于OP的评论说他是自托管的,所以解决方案不是HTTPModule
,而是IDispatchMessageInspector.BeforeSendReply
和IDispatchMessageInspector.AfterReceiveRequest
。
授权必须配置为"None"并在IDispatchMessageInspector
中自定义实现/处理-这样您可以在发出401时添加任何头。否则,运行时处理基本Auth将不会在正确/正Auth之前调用IDispatchMessageInspector
。
虽然这可以工作,但要注意,这意味着您自己实现安全敏感代码,因此需要采取适当的措施来确保其正确实现…
将以下行添加到WCF服务中调用的第一个方法中对我有效。
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
要求以下导入
System.ServiceModel.Web;
参考原文
我尝试了很多方法,但找不到任何东西,然后突然在最后我知道头应该通过OPTIONS请求只发送,然后我在这里找到了一些有用的SO代码!这个完全解决了我的问题。
实际上这里的重点是你必须在OPTIONS请求中添加标头以及200 OK响应,这就是在这个链接上所做的。