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?

WCF REST服务中的CORS支持

这家伙救了我的命。

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.BeforeSendReplyIDispatchMessageInspector.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响应,这就是在这个链接上所做的。