在AngularJS中跨域HTTP请求失败

时间:2022-03-30 04:04:02

I have a REST backend with Spring (CORS enabled running on Apache Tomcat 7) and an AngularJS client. Both running on different domains (as far as CORS is concerned).

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

I'm trying to implement Basic Auth but it only works when both the client and the service are on the same host/port number even after I verified that CORS is working fine on the server side. (I tested it by disabling basic auth impl and simply checking if the client is able to pull data from service. It works as long as the CORS filter on the service is working - as expected).

我正在尝试实现基本的Auth,但它只在客户端和服务在相同的主机/端口号上运行时才有效,即使我验证了CORS在服务器端运行良好。(我通过禁用基本的auth impl测试它,并检查客户端是否能够从服务中提取数据。只要服务上的CORS过滤器如预期的那样工作,它就可以工作。

Here is the client configuration

这是客户端配置

Enabling Cross domain request for Angular (I heard that it's not needed for Angular 1.2+ but it doesn't seem to work either way)

允许对角的交叉域请求(我听说角1。2+不需要它,但两种方法都不行)

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

HTTP Call

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

Backend CORS Filter

后端歌珥过滤器

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 for Basic Auth

基本安全的弹簧

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

Error I get (The whole error as-is per request made by the client to the service while running on another domain)

我得到的错误(在另一个域上运行时,客户端对服务发出的每个请求的全部错误)

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 header

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

So as you can see, Angular is unable to deal with the CORS pre-flight OPTIONS even afte the appropriate config is written. Everything works fine in the same domain and the CORS filter in the backend is tested to work independently. So not sure what I'm missing here. Thanks!

如您所见,即使编写了适当的配置,angle也无法处理CORS飞行前选项。在相同的域中,所有东西都可以正常工作,后端中的CORS过滤器被测试为独立工作。所以我不确定我在这里遗漏了什么。谢谢!

1 个解决方案

#1


3  

I assumed that the problem was with my client but as Ray pointed out, it was with my Service.

我以为问题出在我的客户身上,但正如雷指出的,问题出在我的服务上。

Once I knew that I need to debug my service, I downloaded the sources of CORSFilter, put break points appropriately to study the server response.

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

Doing so, I found out that the CORS filter is throwing an exception when it encountered "Authorization" in the request Headers. This is because I did not add it to the list of supported headers. The problem was resolved soon after I added it to the list.

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

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

#1


3  

I assumed that the problem was with my client but as Ray pointed out, it was with my Service.

我以为问题出在我的客户身上,但正如雷指出的,问题出在我的服务上。

Once I knew that I need to debug my service, I downloaded the sources of CORSFilter, put break points appropriately to study the server response.

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

Doing so, I found out that the CORS filter is throwing an exception when it encountered "Authorization" in the request Headers. This is because I did not add it to the list of supported headers. The problem was resolved soon after I added it to the list.

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

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