междоменная аутентификация jquery

Я настраиваю свой сервер Jetty на разрешение междоменных HTTP-запросов (allowedOrigins = *), а также на междоменную аутентификацию (allowCredentials=true) с использованием CrossOriginFilter. Междоменные HTTP-запросы без требования аутентификации работают нормально. Теперь, когда дело доходит до HTTP-вызовов, требующих аутентификации, использование JQuery не работает. Я использую следующий код и следую этому примеру: http://www.aswinanand.com/2009/01/http-basic-authentication-using-ajax/

function login(username, password) {
$.ajax({
    type: "GET",
    contentType: "application/json",
    dataType: "json",
    url: url,
    beforeSend: function(xhr) {
        var base64 = Base64.encode(username + ":" + password);
        xhr.setRequestHeader("Authorization", "Basic " + base64);
        xhr.withCredentials = true;
    },
    error: function(data){
        alert("error");
    },
    success: function(data){
        alert("success"); 
    }
});

В HTTPFox я вижу следующий запрос к серверу:

OPTIONS /login HTTP/1.1
...
Access-Control-Request-Method   GET
Access-Control-Request-Headers  authorization,content-type

Сервер отвечает сообщением

HTTP/1.1 204 No Content
...
Allow   OPTIONS,GET,HEAD

Я также использовал варианты ниже, которые не имеют значения.

$.ajax({
    ...
    username: username,
    password: password,
    ...
}

Функция ошибки срабатывает всегда. Кто-нибудь знает, в чем может быть проблема?


person hansi    schedule 26.05.2012    source источник
comment
Вы видите это в заголовке вашего ответа Access-Control-Allow-Origin:*? Кстати, отличный вопрос! Добро пожаловать в StackOverflow!   -  person jmort253    schedule 27.05.2012
comment
Я думаю, было бы полезно, если бы вы также могли показать любые трассировки стека, связанные с проблемой.   -  person jmort253    schedule 27.05.2012
comment
Хорошо, проверьте, включен ли этот заголовок в ваш ответ. Если нет, то, возможно, безопасность переопределяет заголовки ответа. Необходимо просмотреть больше журналов для дальнейшей отладки. Удачи! :)   -  person jmort253    schedule 27.05.2012
comment
@ jmort253: нет, я не вижу этот заголовок в ответе сервера. Безопасность причала? Какие журналы или трассировки стека я могу предоставить?   -  person hansi    schedule 27.05.2012
comment
Это будет на уровне фреймворка или сервера. Сервер обычно регистрирует вещи на гораздо более низком уровне, чем ваше приложение, поэтому вам нужно изменить logging.properties (или любой другой регистратор, который вы используете) и настроить его для регистрации в DEBUG или ALL, чтобы вы могли видеть, что сервер и инфраструктура делают под капотом. Вы ищете любой экземпляр заголовков, устанавливаемых без заголовка Access-origin.   -  person jmort253    schedule 27.05.2012


Ответы (3)


Поскольку разрешенные заголовки по умолчанию

X-Requested-With, Content-Type, Accept, Origin

Я должен был добавить заголовки

авторизация, тип контента

Нашел это через файл журнала

DEBUG [2012-05-27 17:04:02,468] org.eclipse.jetty.servlets.CrossOriginFilter: заголовки [authorization,content-type] не входят в число разрешенных заголовков [X-Requested-With, Content-Type, Accept, Origin ]

Спасибо за все подсказки!

person hansi    schedule 27.05.2012

Заголовки ответа, которые вы установили в своем приложении, - когда безопасность не включена, 00 работают просто отлично, как вы подтвердили. Однако, когда безопасность включена, ваши междоменные запросы завершатся ошибкой.

Вероятно, это связано с дополнительным фильтром и дополнительными заголовками ответа, которые устанавливаются фильтром безопасности для создания ответа.

Чтобы решить эту проблему, высокоуровневое решение состоит в том, что вы должны установить свои заголовки ответов до того, как фильтр безопасности установит свои заголовки ответов и/или передаст их клиенту.

Вы также используете Jetty; поэтому вы можете использовать Jetty Cross Origin Filter, чтобы убедиться, что заголовки ответа заданы в цепочке Filter в том порядке, в котором их нужно установить:

Вот список параметров, которые вы можете передать в конфигурацию фильтра в web.xml:

  • allowOrigins — разделенный запятыми список источников, которым разрешен доступ к ресурсам. Значение по умолчанию — *, что означает все источники.

  • allowMethods — разделенный запятыми список HTTP-методов, которые разрешено использовать при доступе к ресурсам. Значение по умолчанию — ПОЛУЧИТЬ, ПОЛУЧИТЬ.

  • allowHeaders, разделенный запятыми список заголовков HTTP, которые разрешено указывать при доступе к ресурсам. Значение по умолчанию — X-Requested-With.

  • preflightMaxAge — количество секунд, в течение которых предварительные запросы могут кэшироваться клиентом. Значение по умолчанию — 1800 секунд или 30 минут.

  • allowCredentials — логическое значение, указывающее, разрешает ли ресурс запросы с учетными данными. Значение по умолчанию — ложь

По умолчанию заголовок ответа Allowed Origins имеет значение *, что означает, что по умолчанию любой запрос может быть сделан из любого домена. Вам нужно обязательно изменить это, чтобы разрешить только домены, которые вы собираетесь внести в белый список, при условии, что вы не хотите, чтобы каждый запрос от всех доменов был действительным:

Запись web.xml для фильтра:

<web-app ...>
    ...
    <filter>
        <filter-name>cross-origin</filter-name>
        <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>cross-origin</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    ...
</web-app>

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

person jmort253    schedule 26.05.2012

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

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

person user1050755    schedule 11.07.2012