授权的CORS失败(NS_ERROR_DOM_BAD_URI)

时间:2013-04-28 11:14:03

标签: spring angularjs cors

很抱歉发布这篇相当大的帖子。但我没有办法让它变得更小。责备CORS:)

版本:

  • Angularjs版本:1.1.3
  • Jetty版本:8.1.9
  • Jetty Servlets版本:8.1.9.v20130131(用于Jettys CrossOriginFilter)

我想要实现的目标

使用基本授权标题的跨源请求:

  • 来自Angularjs的$ http方法来自localhost:8000
  • 到localhost:8080 / api / user(Spring MVC REST接口)。

问题:

  • HTTPFox显示响应302(NS_ERROR_DOM_BAD_URI)
  • 拒绝对/ api / user的OPTIONS请求
  • 如果发送了Authorization Basic标头,服务器将使用302而不是200进行响应。
  • 所谓的简单CORS标头工作(没有Angularjs Authorization Basic标头集)。
  • Angularjs返回0作为状态(而不是302或200)。
  • 在HTTPFox位置标头的响应标头中重定向,就像授权失败一样
  • 使用Curl(设置了授权标头)进行测试没有任何问题
  • 提供的Base64编码授权字符串是正确的。

问题:

  • 选项302(NS_ERROR_DOM_BAD_URI)的原因是什么?我该如何解决?
  • 为什么Angularjs返回0而不是302或200(似乎是x-requested-with的问题)?
  • 在浏览器中使用Cross Origin对生产来说真是个好主意(好像有很多问题)?

Spring配置的web.xml中的CORS设置:

allowedOrigins: *
allowedMethods: GET,POST,DELETE,PUT,HEAD,OPTIONS
allowedHeaders: origin,content-type,accept,authorization,x-requested-with
supportsCredentials: true

Angularjs http请求(来自:localhost:8000):

$http.get('localhost:8080/api/user', {headers: {'Authorization':'Basic am9obkBqb2huLmNvbTpibGE='}})
  .success(function(data, status, head, config) {
    console.log("success");
    console.log(status);
  })
  .error(function(data, status, head, config) {
    console.log("error");
    console.log(status);
  });

HTTPFox请求标头(来自OPTIONS请求失败):

(Request-Line)  OPTIONS /api/user HTTP/1.1
Host    localhost:8080
User-Agent  Mozilla/5.0 (X11; Linux x86_64; rv:19.0) Gecko/20100101 Firefox/19.0
Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language en-US,en;q=0.5
Accept-Encoding gzip, deflate DNT   1
Origin  localhost:8000
Access-Control-Request-Method   GET
Access-Control-Request-Headers  authorization
Connection  keep-alive

HTTPFox响应标头(来自OPTIONS请求失败):

(Status-Line)   HTTP/1.1 302 Found
Access-Control-Allow-Origin localhost:8000
Access-Control-Allow-Credentials    true
Access-Control-Max-Age  1800
Access-Control-Allow-Methods    GET,POST,DELETE,PUT,HEAD,OPTIONS
Access-Control-Allow-Headers    origin, content-type, accept, authorization, x-requested-with
Location    localhost:8080/login.jsp
Content-Length  0
Server  Jetty(8.1.9.v20130131)

Spring DEBUG日志:

[qtp1172726060-24 - /api/user] DEBUG org.eclipse.jetty.server.Server - REQUEST /api/user on AsyncHttpConnection@c114739,g=HttpGenerator{s=0,h=-1,b=-1,c=-1},p=HttpParser{s=-5,l=10,c=0},r=1
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlet.ServletHandler - chain=CORS->springSecurityFilterChain->spring
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlet.ServletHandler - call filter CORS
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Cross-origin request to /api/user is a preflight cross-origin request
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Access-Control-Request-Method is GET
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Method GET is among allowed methods [GET, POST, DELETE, PUT, HEAD, OPTIONS]
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Access-Control-Request-Headers is authorization
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Headers [authorization] are among allowed headers [origin,  content-type,  accept,  authorization,  x-requested-with]
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Preflight cross-origin request to /api/user forwarded to application
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlet.ServletHandler - call filter springSecurityFilterChain
[qtp1172726060-24 - /api/user] DEBUG org.eclipse.jetty.server.Server - RESPONSE /api/user  302 handled=true
[qtp1172726060-24] DEBUG o.e.jetty.server.AsyncHttpConnection - Enabled read interest SCEP@5deb702b{l(/127.0.0.1:41667)<->r(/127.0.0.1:8080),d=true,open=true,ishut=false,oshut=false,rb=false,wb=false,w=true,i=0r}-{AsyncHttpConnection@c114739,g=HttpGenerator{s=4,h=0,b=-1,c=-1},p=HttpParser{s=0,l=10,c=0},r=1}

Web.xml中:

<!-- CORS related filter (this comes before the security filter -->
<filter>
    <filter-name>CORS</filter-name>
    <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>

    <init-param>
        <param-name>allowedOrigins</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>allowedMethods</param-name>
        <param-value>GET,POST,DELETE,PUT,HEAD,OPTIONS</param-value>
    </init-param>
    <init-param>
        <param-name>allowedHeaders</param-name>
        <param-value>origin, content-type, accept, authorization, x-requested-with</param-value>
    </init-param>
    <init-param>
        <param-name>supportsCredentials</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>CORS</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- Security related filter -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

1 个答案:

答案 0 :(得分:1)

我们在制作中使用CORS,但它只适用于HTML5投诉浏览器,我们遇到了同样的问题。

我们的客户端与您的客户端之间的唯一区别是您没有将withCredentials传递给get方法。

像这样:

$http.get(url, { withCredentials : true })

您也可以设为默认值:

config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.withCredentials = true;
}]);

如果这两项都不起作用,请尝试将CORS servlet更改为this