Аутентификация CAS и перенаправления с JQuery AJAX - PullRequest
9 голосов
/ 02 июня 2010

У меня есть HTML-страница, которая должна отправлять запросы в веб-службу, защищенную CAS ( Central Authentication Service ), используя функции JQuery AJAX. У меня есть следующий код:

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

Переменная request может быть либо на сервере CAS (https://cas.mydomain.com/login?service=myServiceURL), либо непосредственно на службу (которая затем должна быть перенаправлена ​​обратно на CAS, чтобы получить билет службы). Firebug показывает, что запрос выполняется и возвращается как перенаправление 302. Однако функция $.ajax() не обрабатывает перенаправление.

Я написал эту функцию, чтобы обойти это:

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

Однако даже при этом функция handleRedirects никогда не вызывается, а xmlHttp.status всегда возвращает 0. Также не похоже, что файлы cookie отправляются с вызовом cas.mydomain.com. (См. этот вопрос для аналогичной проблемы.)

Это проблема с вызовами AJAX, которые не обрабатывают перенаправления, или здесь происходит больше, чем кажется на первый взгляд?

Ответы [ 3 ]

5 голосов
/ 06 июня 2010

В действительности происходит больше, чем кажется на первый взгляд.

После некоторого расследования выясняется, что запросы JQuery AJAX, сделанные таким образом, не выполняются, если они не переданы в один и тот же поддомен. В этом примере запросы к cas.mydomain.com отправляются с другого сервера. Даже если он также находится на mydomain.com, запрос не будет выполнен, поскольку субдомен не соответствует .

jQuery AJAX правильно обрабатывает перенаправления. Я провёл некоторое тестирование со скриптами на том же поддомене, чтобы убедиться в этом. Кроме того, куки также передаются, как и следовало ожидать. См. мой блог для этого исследования.

Также имейте в виду, что протоколы должны быть одинаковыми. То есть, поскольку cas.mydomain.com использует HTTPS, страница, с которой вы звоните, также должна быть на HTTPS, иначе запрос не будет выполнен.

1 голос
/ 12 февраля 2014

Вы можете совершать такие междоменные вызовы AJAX с помощью прокси PHP. В следующем примере прокси-сервер способен вызывать веб-службы REST, которые возвращают строку 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;

?>

Использование URL

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

JQuery $.ajax или $.post

Обратите внимание, что если вам не нужно передавать имя пользователя и пароль, то достаточно запроса GET.

$.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" }
});
1 голос
/ 01 августа 2013

Междоменные звонки не разрешены браузером. Самый простой способ - использовать JSONP на стороне мобильного приложения и использовать шлюз CAS для возврата билета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...