2010-06-02 12 views
8

Tengo una página HTML que necesita realizar solicitudes a un servicio web CAS-protected (Central Authentication Service) utilizando las funciones jQuery AJAX. Tengo el siguiente código:Autenticación CAS y redireccionamientos con jQuery AJAX

$.ajax({ 
    type: "GET", 
    url: request, 
    dataType: "json", 
    complete: function(xmlHttp) { 
     console.log(xmlHttp); 
     alert(xmlHttp.status); 
    }, 
    success: handleRedirects 
}); 

La variable request puede ser o bien al servidor CAS (https://cas.mydomain.com/login?service=myServiceURL) o directamente al servicio (que luego debe volver a redirigir CAS para obtener un ticket de servicio). Firebug muestra que la solicitud se está realizando y que vuelve como una redirección 302. Sin embargo, la función $.ajax() no está manejando la redirección.

escribí esta función para evitar esto:

var handleRedirects = function(data, textStatus) { 
    console.log(data, textStatus); 
    if (data.redirect) { 
     console.log("Calling a redirect: " + data.redirect); 
     $.get(data.redirect, handleRedirects); 
    } else { 
     //function that handles the actual data processing 
     gotResponse(data); 
    } 
}; 

Sin embargo, a pesar de esto, la función handleRedirects nunca se llama, y ​​la xmlHttp.status siempre devuelve 0. Tampoco parece que las cookies se envíen con la llamada a cas.mydomain.com. (Consulte this question para un problema similar.)

¿Esto es un problema con las llamadas AJAX que no manejan redirecciones, o hay más cosas aquí que lo que parece?

Respuesta

5

De hecho, hay más cosas de lo que parece.

Después de algunas investigaciones, parece que las solicitudes de jQuery AJAX realizadas de esta manera fallan si no están hechas para el mismo subdominio. En este ejemplo, las solicitudes se realizan a cas.mydomain.com desde un servidor diferente. Incluso si también está en mydomain.com, la solicitud fallará porque el subdominio no coincide con.

jQuery AJAX maneja los redireccionamientos correctamente. Hice algunas pruebas con scripts en el mismo subdominio para verificar eso. Además, las cookies también se pasan como es de esperar. Ver my blog post para esta investigación.

También tenga en cuenta que los protocolos deben ser los mismos. Es decir, dado que cas.mydomain.com está utilizando HTTPS, la página desde la que lo está llamando también debe estar en HTTPS o la solicitud fallará.

+1

¿Alguna vez encontró una solución a este problema? Leí tu publicación de blog sugiriendo JSONP, que es lo que he leído en otro lugar. Sin embargo, parece que CORS es la forma de evitar esto, pero todavía no puedo hacer que los redireccionamientos 302 funcionen correctamente. – aasukisuki

0

Las llamadas entre dominios no están permitidas por el navegador. La forma más sencilla sería utilizar JSONP en el extremo de la aplicación móvil y usar una puerta de enlace CAS para devolver un ticket.

1

Puede hacer tales llamadas AJAX entre dominios con un proxy PHP. En el siguiente ejemplo, el proxy puede llamar a servicios web REST que devuelven una cadena JSON.

wsproxy.php

<?php 

if (!isset($_POST["username"]) || !isset($_POST["password"])) 
    die("Username or password not set."); 

$username = $_POST["username"]; 
$password = $_POST["password"]; 

if (!isset($_GET['url']) 
    die("URL was not set."); 

//Rebuild URL (needed if the url passed as GET parameter 
//also contains GET parameters 
$url = $_GET['url']; 
foreach ($_GET as $key => $value) { 
    if ($key != 'url') { 
     $url .= "&" . $key . "=" . $value; 
    } 
} 

//Set username and password for HTTP Basic Authentication 
$context = stream_context_create(array(
    'http' => array(
    'header' => "Authorization: Basic " . base64_encode("$username:$password") 
    ) 
)); 

//Call WS 
$json = file_get_contents($url, false, $context); 

// Read HTTP Status 
if(isset($http_response_header[0])) 
    list($version,$status_code,$msg) = 
     explode(' ',$http_response_header[0], 3); 

// Check HTTP Status 
if($status_code != 200) { 
    if($status_code == 404) { 
     die("404 - Not Found"); 
    } else { 
     die($status_code . " - Error"); 
    } 
} 

//Add content header 
header('Content-Type: application/json'); 
print $json; 

?> 

uso de URL

http://yourDomain.com/wsproxy.php?url=https://wsToCall.com/ws/resource?param1=false&param2=true

jQuery $.ajax o $.post

Tenga en cuenta que si no necesita pasar el nombre de usuario y la contraseña, entonces una solicitud GET es suficiente.

$.ajax({ 
    type : "POST", 
    url : "http://" + document.domain + 
     "/wsproxy.php?url=http://wsToCall.com/ws/resource?param1=false&param2=true", 
    dataType : "json", 
    success : handleRedirects, 
    data: { username: "foo", password: "bar" } 
}); 
+0

Un problema con el que se puede topar con esto es que el proxy no utilizará la información de la sesión del usuario. En mi caso, intenté registrar al usuario en un servicio CAS enviando una solicitud del lado del servidor al servidor CAS; el ticket del servicio que recibí los autenticó en el servicio pero no se registraron en el servidor (perdiendo del beneficio de tener una configuración de SSO para comenzar). – DaveMongoose

Cuestiones relacionadas