xmlHttp.getResponseHeader +不工作的CORS [英] xmlHttp.getResponseHeader + Not working for CORS

查看:179
本文介绍了xmlHttp.getResponseHeader +不工作的CORS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对.NET 4这项服务是用来验证用户的asp.NET WCF。我们提交的用户名和密码,然后HTTP标头应该返回与包括身份验证cookie。使用此工作正常本地托管的测试页。我现在attemtpting访问头信息跨域。我已经安装在不同的机器上我的测试页面,并配置翻过打电话到WCF。该呼叫工作,并在呼叫的数据的答复是正确的。但是,我无法用下面的访问标题信息:

 警报(xmlHttp.getAllResponseHeaders());

 警报(xmlHttp.getResponseHeader(设置Cookie));

使用IE浏览器中的调试器和活HTTP标头插上为Firefox,我可以看到正在返回的头信息。

在我的全局AJAX网页我设置来处理CORS响应。

 私人无效EnableCrossDomainAjaxCall()
{
    HttpContext.Current.Response.AddHeader(访问控制允许原产地,*);
    如果(HttpContext.Current.Request.HttpMethod ==选项。)
    {        HttpContext.Current.Response.AddHeader(缓存控制,无缓存);
        HttpContext.Current.Response.AddHeader(访问控制允许的方法,GET,POST,PUT,DELETE);
        HttpContext.Current.Response.AddHeader(访问控制允许报头,内容类型,接受);        HttpContext.Current.Response.AddHeader(访问控制-max-age的,1728000);
        HttpContext.Current.Response.End();
    }}

这是我用来调用服务的AJAX:

  $(#btnLogin)。点击(函数(五){
            VAR的getURL;
            的getURL = $阿贾克斯({
                //类型:POST,
                键入:GET,
                的contentType:应用/ JSON的;字符集= UTF-8,
                网址:'http://10.0.4.66/AuthenticationService.svc/Login?Name=test&password=pwsd',
                //网址:'../SecurityServer/AuthenticationService.svc/Login?Name=test&password=pwsd',
                数据类型:JSONP
                错误:功能(请求,状态,错误){
                    警报('出错');
                },
                跨域:真实,
                成功:功能(数据,textStatus,XMLHTTP){
                    //警报(xmlHttp.getResponseHeader(内容类型));
                    的document.write(xmlHttp.getResponseHeader(内容类型)+< BR />中);
                    警报(xmlHttp.getAllResponseHeaders());
                    警报(xmlHttp.getResponseHeader(设置Cookie));
                    VAR标题='';
                    VAR headerPair = xmlHttp.getAllResponseHeaders('wcfCookie')分裂(\\ r \\ n);
                    无功输出='';
                    $。每个(headerPair,功能(键,线){
                        VAR部分= line.split(':');                        如果(部件[0] =='wcfCookie'){
                            ChocChip =零件[1]
                            返回false
                        }                    });                }            });

下面是我的头信息从活HTTP标头

抓起

 日期:星期一,2013年2月4日12时12分40秒GMT
服务器:Microsoft-IIS / 6.0
的X已启动方式:ASP.NET
的X ASPNET-版本:4.0.30319
访问控制允许来源:*
设置Cookie: wcfCookie=8D38D5D6A0F138FEB595DD016F7694EDDF3E6757C82ED3D419F5047A5294974C1885487465CEC0A0BCC2B3802C7B03FF9F5370A05D4CCBDDDABCB1558C3816044BF4F78209BF38C6B1A7CAD34CD3C85C40B8515CFB1C2B2694BC78803D8DACB4
内容长度:65
缓存控制:应用/ JSON的;字符集= UTF-8
内容类型:应用程序/ x-的javascript


解决方案

首先,一点背景:

您正在使用接入控制允许标题,指定哪个要求的标头中的客户端被允许的发送,但你不能指定哪些响应的标头中的客户端被允许的阅读的。为了让客户端读取非简单响应头,你需要使用访问控制展露-标题。从 HTML5岩石CORS页面


  

在一个CORS请求, getResponseHeader()方法只能访问简单的响应头。简单的响应头定义如下:


  
  

      
  • 的Cache-Control

  •   
  • 内容语言

  •   
  • 内容类型

  •   
  • 过期

  •   
  • 的Last-Modified

  •   
  • 杂注

  •   

  
  

如果您希望客户端能够访问其他头,您必须使用访问控制展露-标题头。标题的值是您希望暴露给客户端的响应报头的逗号分隔的列表。


所以,考虑到新的信息,你可以这样做:

  HttpContext.Current.Response.AddHeader(访问控制展露报头,设置Cookie);

...但有更多的给它比。

现在,实际的答案:

有这里有一个更严重的问题:XHR规范 explictily不允许读设置Cookie 。这是因为这是一个功能的跨域的Cookie窃取攻击

假设域A做跨域请求域B.当域B套饼干,它的设定特定领域的饼干的只域B 的。任何企图通过域A读取域B的饼干是违反对Cookie的使用同源的政策。

我不知道WCF,所以我不是肯定的最好的方法的真正的你想要做什么,但我猜的解决方案可能是通过传递一个身份验证令牌不饼干(例如, X-WCF的验证头?)域A读取信息,然后确定自己的cookie。

I have an asp.NET WCF on .NET 4. This service is used to authenticate users. We are submitting a username and password and then an HTTP Header should be returned with the authentication cookie included. Using a locally hosted test page this is working correctly. I am now attemtpting to access the header information cross domain. I have installed my test page on a different machine and configured to call accross to the WCF. The call is working and the 'data' reply in the call is correct. However, I am unable to access the header information with either of the following:

alert(xmlHttp.getAllResponseHeaders());

or

 alert(xmlHttp.getResponseHeader("Set-Cookie"));

Using the debugger in IE and the 'Live HTTP Header' plug in for Firefox, I can see the header information is being returned.

In my global ajax page I am setting the response to handle CORS.

  private void EnableCrossDomainAjaxCall()
{
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");


    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {

        HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");

        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    }

}

This is the AJAX I am using to call the service:

$("#btnLogin").click(function (e) {
            var geturl;
            geturl = $.ajax({
                // type: "POST",
                type: "GET",
                contentType: "application/json; charset=utf-8",
                url: 'http://10.0.4.66/AuthenticationService.svc/Login?Name=test&password=pwsd',
                // url: '../SecurityServer/AuthenticationService.svc/Login?Name=test&password=pwsd',
                dataType: "jsonp",
                error: function (request, status, error) {
                    alert('Error Occured');
                },
                crossdomain: true,
                success: function (data, textStatus, xmlHttp) {
                    // alert(xmlHttp.getResponseHeader("Content-Type"));
                    document.write(xmlHttp.getResponseHeader("Content-Type") + "<br/>");
                    alert(xmlHttp.getAllResponseHeaders());
                    alert(xmlHttp.getResponseHeader("Set-Cookie"));
                    var headers = '';
                    var headerPair = xmlHttp.getAllResponseHeaders('wcfCookie').split("\r\n");
                    var output = '';
                    $.each(headerPair, function (key, line) {
                        var parts = line.split(':');

                        if (parts[0] == 'wcfCookie') {
                            ChocChip = parts[1]
                            return false
                        }

                    });

                }

            });

Below is my header information grabbed from 'Live HTTP headers'

Date: Mon, 04 Feb 2013 12:12:40 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
Access-Control-Allow-Origin: *
Set-Cookie: wcfCookie=8D38D5D6A0F138FEB595DD016F7694EDDF3E6757C82ED3D419F5047A5294974C1885487465CEC0A0BCC2B3802C7B03FF9F5370A05D4CCBDDDABCB1558C3816044BF4F78209BF38C6B1A7CAD34CD3C85C40B8515CFB1C2B2694BC78803D8DACB4
Content-Length: 65
Cache-Control: application/json; charset=utf-8
Content-Type: application/x-javascript

解决方案

First, a little background:

You are using Access-Control-Allow-Headers, which specifies which request headers the client is allowed to send, but you are not specifying which response headers the client is allowed to read. To allow the client to read non-simple response headers, you need to use Access-Control-Expose-Headers. From the HTML5 Rocks CORS page:

During a CORS request, the getResponseHeader() method can only access simple response headers. Simple response headers are defined as follows:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

If you want clients to be able to access other headers, you have to use the Access-Control-Expose-Headers header. The value of this header is a comma-delimited list of response headers you want to expose to the client.

So, given that new information, you might do:

HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "Set-Cookie");

...but there's more to it than that.

Now, the actual answer:

There's one more serious problem here: the XHR specification explictily disallows reading Set-Cookie. That's because this is functionally a cross-domain cookie-stealing attack.

Suppose domain A makes a cross-domain request to domain B. When domain B sets cookies, it's setting domain-specific cookies for domain B only. Any attempt by domain A to read domain B's cookies is a violation of the same-origin policy for cookie access.

I don't know WCF, so I'm not the sure of best way to actually do what you want, but I'd guess the solution might be to pass an auth token not through cookies (e.g., a X-WCF-Auth header?) that domain A reads and then sets its own cookie.

这篇关于xmlHttp.getResponseHeader +不工作的CORS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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