10

Я построил REST API backend с Spring MVC и получил базовый Auth с Spring Security.JQuery перекрестный домен базовый вызов auth

Я хотел бы сделать перекрестный домен ajax-вызов API REST от клиентов Javascript. Я не хочу использовать JSONP, потому что я не хочу ограничиваться вызовами GET. Я использую CORS, и я поставил правильные заголовки на стороне сервера.

Предположим, что мой REST API находится на домене localhost: 8087 и мой клиент на localhost: 8086, который является перекрестным вызовом домена.

В моем клиенте Javascript, я сделать вызов Ajax с JQuery:

<script> 
     $.ajax ({ 
      url: "http://localhost:8087/SpringMVC/users/user1", 
      beforeSend: function (xhr) { xhr.setRequestHeader ("Authorization", "Basic xxxxxxxxxxxx"); }, 
      success: function(val) { console.log(val); alert("success" + val); }, 
      error: function(val) { console.log(val); alert("error" + val); } 
     }); 
</script> 

Моя проблема заключается в том, что Jquery не посылает заголовок авторизации в запросе HTTP и я не знаю почему. Я не понимаю, потому что я делаю это в методе beforeSend, поэтому он должен быть внутри HTTP-запроса. Результат: у меня ошибка 401.

Когда я пытаюсь выполнить скрипт с того же домена localhost: 8087, который больше не является перекрестным доменом, у меня нет проблем.

Как это возможно?

Мой сценарий - всего лишь тест. Я не собираюсь указывать свое имя пользователя/пароль на стороне клиента. Но я хочу проверить, как делать ajax-вызовы для базового защищенного REST API. Я предполагаю, что мне нужно отправить на сервер стороне, чтобы защитить мое имя пользователя/пароль, REST API отправляет мне cookie, и мне больше не нужно передавать имя пользователя/пароль для моих следующих вызовов ajax в REST API. Я прав ?

Я проверил свой REST API с клиентом Chrome Advanced REST и работает так. Для первого запроса мне нужно передать заголовок авторизации. Тогда это не нужно. Должен ли он работать так же, как с моим веб-клиентом javascript? Я собираюсь использовать Node.JS с Backbone для его создания.

Большое спасибо.

EDIT2: Похоже, что это проблема с браузером CORS. Я добавил метод Access-Control-Allow-Methods для метода OPTIONS на стороне сервера, и он работает в Chrome. У меня есть доступ к ответу JSON без каких-либо ошибок. Но мне все еще нужно использовать заголовок авторизации для следующих запросов. Как сообщить jQuery, чтобы использовать отправленный куки?

И когда я пытаюсь с Firefox 11, у меня нет доступа к ответу JSON и у меня есть ошибки:

"NetworkError: 401 Non-Autorisé - http://localhost:8087/SpringMVC/users/user1" 
+0

Вы используете base64, кодируя свое имя пользователя/пароль? –

+0

Да, я ставлю xxxxxxxx вместо реального имени пользователя: password. – rico

ответ

8

Видимо, Chrome и Firefox лечения Междоменные прошу немного по-другому. Перед выполнением запроса кросс-домена они выполняют так называемый запрос «предполетный» с помощью метода HTTP OPTIONS. Разница между Chrome и Firefox заключается в том, что Chrome отправляет также заголовок авторизации с учетными данными, а Firefox - нет.

Тогда проблема остается в конфигурации Spring Security. Мой url/users/* защищен для всех HTTP-методов, включая OPTIONS. В случае Firefox, поскольку заголовок авторизации не отправляется, мой запрос не разрешен. Если я ограничу свой безопасный url/users/* только методом GET, то он отлично работает для Firefox.Таким образом, я должен был только добавить, что в моей Spring конфигурации безопасности:

<intercept-url pattern="https://stackoverflow.com/users/*" access="isAuthenticated()" method="GET"/> 

После этого у меня есть выбор: я могу добавить другие методы, чтобы быть обеспеченным в перехватывают-URL, кроме OPTIONS, или я могу ограничить HTTP вызов метода GET в моем контроллере MVC Spring, который даже будет обрабатывать мои вызовы OPTIONS в соответствии с Javadoc. Я выбрал второе решение. Но если кто-то найдет решение заставить Firefox отправить учетные данные, такие как Chrome, это было бы здорово, и я бы выбрал этот.

2

Другой вариант сценария конфигурации Spring Security, представленный Rico будет:

<http ... use-expressions="true"> 
    <intercept-url pattern="https://stackoverflow.com/users/*" access="permitAll" method="OPTIONS"/> 
    <intercept-url pattern="https://stackoverflow.com/users/*" access="isAuthenticated()"/> 
    ... 
</http> 

HTTP OPTIONS запросы всегда будет проходить через проверку подлинности и любой другой метод HTTP не будет.

Примечание: use-expressions Атрибут XML установлен в true в <http> элемент. Spring Security будет ожидать, что access атрибуты <intercept-url> элементов содержат Spring EL выражения, как permitAll и isAuthenticated().