WCF REST 服务中的 CORS 支持 [英] CORS Support within WCF REST Services

查看:22
本文介绍了WCF REST 服务中的 CORS 支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 WCF REST 服务托管在 Windows 服务中,我想发送 Access-Control-Allow-Origin HTTP 标头(定义为 CORS) 与每个响应.

I have a WCF REST service hosted within a Windows service and I would like to send the Access-Control-Allow-Origin HTTP header (defined as part of CORS) with every response.

我尝试的解决方案是在 IDispatchMessageInspector 实现:

My attempted solution was to have something like the following within an IDispatchMessageInspector implementation:

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 标头没有添加到初始交换中.

Normally this would work, but unfortunately my service also uses HTTP basic authorization, which means that when a request comes in without the Authorization header, WCF automatically sends a 401 response asking for credentials. Unfortunately WCF does not call my IDispatchMessageInspector during this initial exchange, so Access-Control-Allow-Origin header is not added to the initial exchange.

当我尝试从浏览器调用服务时出现问题.CORS 指定仅当源域与 Access-Control-Allow-Origin 响应标头中列出的域匹配时才允许跨域请求(* 匹配所有域).不幸的是,当浏览器看到没有 Access-Control-Allow-Origin 标头的初始 401 响应时,它会阻止访问(根据 同源策略).

The problem occurs when I try to call the service from a browser. CORS specifies that cross-origin requests should only be allowed if the origin domain matches the domain listed in the Access-Control-Allow-Origin response header (* matches all domains). Unfortunately when the browser sees the initial 401 response without the Access-Control-Allow-Origin header, it prevents access (according to the same origin policy).

有没有办法在 WCF 自动发送的初始 401 响应中添加标头?

Is there any way add a header to the initial 401 response sent automatically by WCF?

推荐答案

这个人救了我一天.

http://blogs.microsoft.co.il/blogs/idof/archive/2011/07.aspx

我要把他的一些笔记放在这里,以防万一那个网页有一天会死掉.(我讨厌找到你的答案是对的"链接,然后链接就失效了.)

I am going to place some of his notes here, just in case that web page dies some day. (I hate finding "Your answer is right HERE" links, and then the link is dead.)

<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"的可下载库.

Now, you have to find his downloadable library called "WebHttpCors.dll".

但是有足够的(上面)可以帮助您通过 google/bing 找到解决方案.

But there is enough there (above) to help you google/bing your way to a resolution.

让我陷入循环的部分(在我的场景中)是 IE 正在运行,但 Firefox 无法运行.

The part that was throwing me for a loop (in my scenario) is that IE was working, but Firefox was not working.

我的原始页面是:

http://localhost:53692/test/WCFCallTestViaJQ14.htm

所以我的服务在:

http://localhost:8002/MyWCFService/MyWCFMethodByWebGet?state=NC&city=Raleigh

所以我有 localhost <<-->> localhost 流量.

So I had localhost <<-->> localhost traffic.

**** 但是端口不同.(53692 和 8002)****

**** But the ports were different. (53692 and 8002) ****

IE 没问题.Firefox 对此不满意.

IE was ok with it. Firefox was not ok with it.

然后你必须记住,每个浏览器以不同的方式处理他们的 .Send() 请求(在 JQUERY 中).

Then you gotta remember that each browser handles their .Send() requests differently (inside JQUERY that is).

现在一切都说得通了.

//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!";

}

这里有一些我一直在谷歌上搜索/搜索的关键词和短语,最终把我带到了某个地方.

Here are some key words, phrases that I've been googling/binging that finally led me somewhere.

    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

现在,您需要阅读他的博客博客以了解代码在做什么:

NOW, YOU NEED TO READ HIS BLOG BLOGS TO UNDERSTAND WHAT THE CODE IS DOING:

例如,他说:

值为*"的Access-Control-Allow-Origin"标头

"Access-Control-Allow-Origin" header with the value of "*"

这可能是您想要的,也可能不是.您可能希望更好地控制此值(标题)和其他值(方法和来源).

This may or may not be what you want. You may want to have better control of this value (headers) and the others (methods and the origins).

开发环境是一回事.(使用您想要的所有 *).

Development environment is one thing. (Use all the *'s you want).

生产是另一回事,您可能希望将这些 * 值调整为更具区别性的值.简而言之,您需要了解 CORS 在安全方面实际上为您做什么,而不仅仅是添加一种让一切都进入的行为.

Production is something else, you may want to tweak down those * values to something more discriminate. In a nutshell, you need to understand what CORS is actually doing for you in terms of security, and not just add a behavior that lets everything in.

  allowed-origins: '*'
  allowed-headers: '*'
  allowed-methods: '*'

这篇关于WCF REST 服务中的 CORS 支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆