AngularJS中的跨域HTTP请求失败

时间:2014-02-26 19:01:27

标签: angularjs java-ee spring-security cors http-basic-authentication

我有一个带有Spring的REST后端(在Apache Tomcat 7上运行CORS)和一个AngularJS客户端。两者都在不同的域上运行(就CORS而言)。

我试图实现Basic Auth但它只在客户端和服务都在同一主机/端口号上时才有效,即使我验证了CORS在服务器端工作正常。 (我通过禁用基本auth impl并简单地检查客户端是否能够从服务中提取数据来测试它。只要服务上的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的飞行前OPTIONS。一切都在同一个域中正常工作,后端的CORS过滤器经过测试可以独立工作。所以不确定我在这里失踪了什么。谢谢!

1 个答案:

答案 0 :(得分:3)

我认为问题出在我的客户身上,但Ray指出,这是我的服务。

一旦我知道我需要调试我的服务,我下载了CORSFilter的来源,适当地设置了断点以研究服务器响应。

这样做,我发现CORS过滤器在请求Headers中遇到“Authorization”时抛出异常。这是因为我没有将它添加到支持的标题列表中。我把它添加到列表后很快就解决了这个问题。

corsFilter.setInitParameter("cors.supportedHeaders", "Accept, Origin, X-Requested-With, Content-Type, Last-Modified, Authorization");