Сбой междоменного HTTP-запроса в AngularJS

У меня есть бэкэнд REST с Spring (CORS включен на Apache Tomcat 7) и клиент AngularJS. Оба работают в разных доменах (что касается CORS).

Я пытаюсь внедрить Basic Auth, но он работает только тогда, когда и клиент, и служба находятся на одном хосте/номере порта, даже после того, как я убедился, что CORS работает нормально на стороне сервера. (Я проверил это, отключив базовую реализацию аутентификации и просто проверив, может ли клиент извлекать данные из службы. Это работает, пока работает фильтр CORS в службе - как и ожидалось).

Вот конфигурация клиента

Включение междоменного запроса для Angular (я слышал, что он не нужен для Angular 1.2+, но, похоже, он в любом случае не работает)

myApp.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.defaults.useXDomain = true;
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
 }]);

HTTP-вызов

 $http({method: 'GET', url: url + userId, headers: {'Authorization': 'Basic ' + Base64.encode('admin' + ':' + 'password')}}).
    success(function(data, status, headers, config) {
//
    }).
    error(function(data, status, headers, config) {
//
    });

Серверный CORS-фильтр

FilterRegistration corsFilter = container.addFilter("CORS", CORSFilter.class);
corsFilter.setInitParameter("cors.supportedMethods", "GET, HEAD, POST, PUT, DELETE, OPTIONS");
corsFilter.setInitParameter("cors.supportedHeaders", "Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
corsFilter.setInitParameter("cors.supportsCredentials ", "false");
corsFilter.setInitParameter("cors.allowOrigin ", "*");
corsFilter.addMappingForUrlPatterns(null, false, "/*");

Spring Security для базовой аутентификации

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("admin").password("password").roles("USER", "ADMIN");
    }


     @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/**").hasRole("USER")
        .anyRequest().anonymous()
        .and()
        .httpBasic();
  }    
}

Ошибка, которую я получаю (вся ошибка как есть для каждого запроса, сделанного клиентом службе во время работы в другом домене)

Failed to load resource: the server responded with a status of 403 (Forbidden) (11:53:44:206 | error, network)
  at http://localhost:8081/myApp-service/user/6
Failed to load resource: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8383' is therefore not allowed access. (11:53:44:209 | error, network)
  at http://localhost:8081/myApp-service/user/6
XMLHttpRequest cannot load http://localhost:8081/myApp-service/user/6. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8383' is therefore not allowed access. (11:53:44:211 | error, javascript)
  at app/index.html

Заголовок запроса Chrome

Request URL:http://localhost:8081/myApp-service/user/6
Request Method:OPTIONS
Status Code:403 Forbidden
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, authorization
Access-Control-Request-Method:GET
Connection:keep-alive
Host:localhost:8081
Origin:http://localhost:8383
Referer:http://localhost:8383/myApp-client/app/index.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36
Response Headersview source
Content-Length:93
Content-Type:text/plain;charset=ISO-8859-1
Date:Wed, 26 Feb 2014 18:55:00 GMT
Server:Apache-Coyote/1.1

Итак, как вы можете видеть, Angular не может работать с ПАРАМЕТРАМИ предварительной проверки CORS даже после того, как соответствующая конфигурация написана. Все работает нормально в том же домене, а фильтр CORS в бэкенде тестируется на независимую работу. Так что не уверен, что мне здесь не хватает. Спасибо!


person user6123723    schedule 26.02.2014    source источник
comment
Проблема связана с кодом вашего сервера, а не с Angular. Глядя на ответ, вы можете увидеть, что ваш сервер неправильно обрабатывает файл OPTIONS/preflight.   -  person Ray Nicholus    schedule 26.02.2014
comment
@RayNicholus Это действительно звучит разумно. Я только подозревал клиента до сих пор. Поскольку мой фильтр CORS уже принимает OPTIONS, я не могу придумать никаких других изменений, которые я могу внести, чтобы серверная часть работала. Любые идеи?   -  person user6123723    schedule 27.02.2014
comment
Похоже, ваш сервер возвращает код состояния 403. Вероятно, вы захотите выяснить, почему он это делает.   -  person Ray Nicholus    schedule 27.02.2014
comment
Вы захотите посмотреть точный ответ, который ваш сервер отправляет в OPTIONS через прокси.   -  person Ray Nicholus    schedule 27.02.2014


Ответы (1)


Я предположил, что проблема была с моим клиентом, но, как указал Рэй, это была моя служба.

Как только я понял, что мне нужно отлаживать свой сервис, я скачал исходники CORSFilter, поставил соответствующие точки останова, чтобы изучить ответ сервера.

При этом я обнаружил, что фильтр CORS выдает исключение, когда обнаруживает «Авторизацию» в заголовках запроса. Это потому, что я не добавил его в список поддерживаемых заголовков. Проблема была решена вскоре после того, как я добавил его в список.

corsFilter.setInitParameter("cors.supportedHeaders", "Accept, Origin, X-Requested-With, Content-Type, Last-Modified, Authorization");
person user6123723    schedule 26.02.2014
comment
где вы помещаете этот мир кода? У меня такая же проблема с моим приложением spring security + angularjs... - person skywalker; 02.07.2015
comment
@NevyanovL mvnrepository.com/artifact/com.thetransactioncompany/ - person user6123723; 02.07.2015