xmlHttp.getResponseHeader + No funciona para CORS

4 minutos de lectura

xmlHttp.getResponseHeader + No funciona para CORS
usuario2039547

Tengo un asp.NET WCF en .NET 4. Este servicio se usa para autenticar a los usuarios. Estamos enviando un nombre de usuario y contraseña y luego se debe devolver un encabezado HTTP con la cookie de autenticación incluida. Usando una página de prueba alojada localmente, esto funciona correctamente. Ahora estoy intentando acceder al dominio cruzado de información del encabezado. Instalé mi página de prueba en una máquina diferente y la configuré para llamar a WCF. La llamada está funcionando y la respuesta de “datos” en la llamada es correcta. Sin embargo, no puedo acceder a la información del encabezado con ninguno de los siguientes:

alert(xmlHttp.getAllResponseHeaders());

o

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

Usando el depurador en IE y el complemento ‘Live HTTP Header’ para Firefox, puedo ver que se devuelve la información del encabezado.

En mi página global de ajax, estoy configurando la respuesta para manejar 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();
    }

}

Este es el AJAX que estoy usando para llamar al servicio:

$("#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("rn");
            var output="";
            $.each(headerPair, function(key, line) {
                var parts = line.split(':');

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

            });
        }
    });

A continuación se muestra la información de mi encabezado extraída de ‘Encabezados HTTP en vivo’

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

xmlHttp.getResponseHeader + No funciona para CORS
apsilleres

Primero, un poco de historia:

Tu estas usando Access-Control-Allow-Headersque especifica qué solicitud encabezados que el cliente tiene permitido enviarpero no estás especificando cuál respuesta encabezados que el cliente tiene permitido leer. Para permitir que el cliente lea encabezados de respuesta no simples, debe usar Access-Control-Expose-Headers. Desde el Página CORS de rocas HTML5:

Durante una solicitud CORS, el getResponseHeader() El método solo puede acceder a encabezados de respuesta simples. Los encabezados de respuesta simple se definen de la siguiente manera:

  • Control de caché
  • Contenido-Idioma
  • Tipo de contenido
  • Caduca
  • Última modificación
  • pragma

Si desea que los clientes puedan acceder a otras cabeceras, debe utilizar el Access-Control-Expose-Headers encabezamiento. El valor de este encabezado es una lista delimitada por comas de encabezados de respuesta que desea exponer al cliente.

Entonces, dada esa nueva información, podrías hacer:

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

…pero hay más que eso.

Ahora, la respuesta real:

Aquí hay un problema más serio: la especificación XHR prohíbe explícitamente la lectura Set-Cookie. Eso es porque esto es funcionalmente un ataque de robo de cookies entre dominios.

Supongamos que el dominio A realiza una solicitud entre dominios al dominio B. Cuando el dominio B establece cookies, está configurando cookies específicas del dominio. solo para el dominio B. Cualquier intento del dominio A de leer las cookies del dominio B es una violación de la política del mismo origen para el acceso a las cookies.

No sé WCF, así que no estoy seguro de la mejor manera de Realmente haga lo que quiera, pero supongo que la solución podría ser pasar un token de autenticación no a través de cookies (por ejemplo, un X-WCF-Auth encabezado?) que el dominio A lee y luego establece su propia cookie.

xmlHttp.getResponseHeader + No funciona para CORS
mártir

Las políticas de seguridad del navegador pueden bloquear su respuesta porque no ha configurado:

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

Si eso no ayuda, intente agregar

xhrFields: { withCredentials: true }

para usted ajax las opciones también pueden valer la pena intentarlo.

.

¿Ha sido útil esta solución?