2013-02-04 10 views
17

Ich habe eine asp.NET WCF auf .NET 4. Dieser Dienst verwendet wird, um Benutzer zu authentifizieren. Wir senden einen Benutzernamen und ein Passwort und dann sollte ein HTTP-Header mit dem Authentifizierungs-Cookie zurückgegeben werden. Mit einer lokal gehosteten Testseite funktioniert das korrekt. Ich versuche jetzt, auf die Header-Information Cross-Domain zuzugreifen. Ich habe meine Testseite auf einem anderen Computer installiert und konfiguriert, um den WCF anzurufen. Der Anruf funktioniert und die Antwort "Daten" im Anruf ist korrekt. Allerdings kann ich die Header-Informationen mit einer der folgenden zuzugreifen:xmlHttp.getResponseHeader + Nicht für CORS arbeiten

alert(xmlHttp.getAllResponseHeaders()); 

oder

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

Mit dem Debugger in IE und die 'Live HTTP Header' Plug-in für Firefox, ich kann siehe die Kopfzeileninformationen werden zurückgegeben.

In meiner globalen Ajax-Seite Ich gründe die Antwort CORS zu handhaben.

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(); 
    } 

} 

Dies ist die AJAX Ich bin mit dem Service zu nennen:

$("#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 
         } 

        }); 

       } 

      }); 

Unten ist mein Header-Informationen

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 

Antwort

0

Der Browser des Sicherheitsrichtlinien von 'Live HTTP headers' packte könnte blockieren Ihre Antwort, weil Sie nicht festgelegt haben:

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials","true"); 

Wenn das, versuchen nicht hilft einen Versuch wert könnte auch sein

xhrFields: { withCredentials: true } 

auf Ihre ajax Optionen hinzuzufügen.

55

Zuerst ein wenig Hintergrund:

Du Access-Control-Allow-Headers verwenden, die auf die Anforderung spezifiziert ist Header der Client senden erlaubt, aber geben Sie an, nicht die Antwort Header der Client erlaubt lesen. Damit der Client nicht-einfache Antwortheader lesen kann, müssen Sie Access-Control-Expose-Headers verwenden. Vom HTML5 Rocks CORS page:

Während eines CORS Anfrage kann das getResponseHeader() Methode zugreifen nur einfache Antwort-Header. Einfache Antwort-Header sind wie folgt definiert:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Verfällt
  • Last-Modified
  • Pragma

Wenn Wenn Sie möchten, dass Clients auf andere Header zugreifen können, müssen Sie Access-Control-Expose-Headers verwenden Header.Der Wert dieses Headers ist eine durch Kommas getrennte Liste von Antwortheadern, die Sie dem Client bereitstellen möchten.

So gegeben, dass neue Informationen, könnten Sie tun:

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

... aber es gibt noch mehr zu bieten als das.

nun die tatsächliche Antwort:

Es gibt ein ernsteres Problem hier: die XHR-Spezifikation explictily disallows reading Set-Cookie. Das liegt daran, dass dies funktionell ein Cross-Domain-Cookie-Diebstahl-Angriff ist.

Angenommen, Domäne A erstellt eine domänenübergreifende Anforderung an Domäne B. Wenn Domäne B Cookies setzt, werden domänenspezifische Cookies nur für Domäne B festgelegt. Jeder Versuch von Domain A, die Cookies von Domain B zu lesen, verstößt gegen die Richtlinien für den Cookie-Zugriff.

Ich weiß nicht WCF, also bin ich nicht der sicherste Weg zu eigentlich tun, was Sie wollen, aber ich würde vermuten, die Lösung könnte sein, ein Authentifizierungs-Token nicht durch Cookies (z. B. ein X-WCF-Auth header?) dass Domain A liest und setzt dann seinen eigenen Cookie.