2010-06-02 8 views
8

J'ai une page HTML qui doit faire des demandes à un service Web protégé par CAS (Central Authentication Service) en utilisant les fonctions jQuery AJAX. J'ai le code suivant:Authentification CAS et redirections avec jQuery AJAX

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

La variable request peut être soit sur le serveur CAS (https://cas.mydomain.com/login?service=myServiceURL) ou directement au service (qui devrait alors rediriger le TAS pour obtenir un ticket de service). Firebug montre que la requête est en cours et qu'elle revient sous la forme d'une redirection 302. Toutefois, la fonction $.ajax() ne gère pas la redirection.

j'ai écrit cette fonction pour contourner ce problème:

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

Cependant, même avec cela, la fonction handleRedirects ne sera jamais appelé, et le xmlHttp.status retourne toujours 0. Il ne semble pas non plus que les cookies soient envoyés avec l'appel cas.mydomain.com. (Voir this question pour un problème similaire.)

Est-ce un problème avec les appels AJAX qui ne traitent pas les redirections, ou y a-t-il plus de choses à faire que ce qui vous vient à l'esprit?

Répondre

5

Il y a en effet plus de choses que rencontre l'oeil.

Après enquête, il semble que les demandes jQuery AJAX faites de cette façon ne s'ils ne sont pas faits à la même sous-domaine. Dans cet exemple, des demandes sont envoyées à cas.mydomain.com à partir d'un serveur différent. Même s'il est également sur mydomain.com, la demande échouera car le sous-domaine ne correspond pas à.

jQuery AJAX ne gère correctement réoriente. J'ai fait quelques tests avec des scripts sur le même sous-domaine pour vérifier cela. En outre, les cookies sont également transmis comme vous le souhaitez. Voir my blog post pour cette recherche.

Gardez à l'esprit que les protocoles doivent être identiques. En effet, puisque cas.mydomain.com utilise HTTPS, la page à partir de laquelle vous l'appelez doit également être sur HTTPS ou la demande échouera.

+1

Avez-vous déjà trouvé une solution à ce problème? J'ai lu votre article de blog suggérant JSONP, qui est ce que j'ai lu ailleurs. Cependant, il semble que CORS est le moyen de contourner ce problème, mais je n'arrive toujours pas à obtenir les redirections 302 pour fonctionner correctement. – aasukisuki

0

Les appels inter-domaines ne sont pas autorisés par le navigateur. Le moyen le plus simple serait d'utiliser JSONP à la fin de l'application mobile et d'utiliser une passerelle CAS pour renvoyer un ticket.

1

Vous pouvez faire ce cross-domain appels AJAX avec un proxy PHP. Dans l'exemple suivant, le proxy est capable d'appeler les services Web REST qui renvoient une chaîne 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; 

?> 

utilisation d'URL

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

jQuery $.ajax ou $.post

Notez que si vous n'avez pas besoin de passer le nom d'utilisateur et mot de passe, puis une requête GET est suffisante.

$.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 problème que vous pourriez rencontrer avec ceci est que le proxy n'utilisera pas les informations de session de l'utilisateur. Dans mon cas, j'essayais de connecter l'utilisateur dans un service CAS en envoyant une requête côté serveur au serveur CAS - le ticket de service que je récupérais les authentifiait sur le service mais ils n'étaient pas connectés au serveur lui-même de l'avantage d'avoir une configuration SSO pour commencer). – DaveMongoose