2013-04-28 300 views
3

對不起,張貼這個相當大的帖子。但我不認爲有辦法讓它變小。要怪就怪CORS :)CORS授權失敗(NS_ERROR_DOM_BAD_URI)

版本:

  • Angularjs版本:1.1.3
  • 碼頭版本:8.1.9
  • 碼頭Servlet的版本:8.1.9.v20130131(用於Jettys CrossOriginFilter )

我想實現

什麼210

跨源請求使用基本授權報頭:

  • 與$ HTTP方法從Angularjs始發從本地主機:8000
  • 到localhost:8080/API /用戶(彈簧MVC REST接口)。

問題:

  • 是HttpFox表明OPTIONS請求/ API /使用者響應302(NS_ERROR_DOM_BAD_URI)被拒絕
  • 服務器與302,而不是200響應如果授權的基本頭是發送。
  • 所謂的簡單CORS標頭工作(沒有Angularjs授權基本標頭集)。
  • Angularjs返回0作爲狀態(而不是302或200)。
  • 在顯示HttpFox的響應頭Location頭重定向彷彿授權失敗
  • 測試與捲曲(有認證頭集)沒有任何問題
  • 提供Base64編碼的授權字符串是正確的工作。

問題:

  • 什麼是OPTIONS 302(NS_ERROR_DOM_BAD_URI)的原因是什麼?我該如何解決它?
  • 爲什麼Angularjs返回0而不是302或200(似乎是x請求的問題)?
  • 使用Cross Origin和瀏覽器真的是一個好主意(看起來好像有很多問題)?

網頁中的CORS設置。Spring配置的XML:

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

Angularjs http請求(起源自:本地主機: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 Response Headers(從失敗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) 

春調試日誌:

[qtp1172726060-24 - /api/user] DEBUG org.eclipse.jetty.server.Server - REQUEST /api/user on [email protected],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 [email protected]{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}-{[email protected],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> 
+0

禁用springSecurityFilterChain工作,放回去,不起作用。錯誤消息肯定是來自瀏覽器,似乎是一箇舊的Netscape消息。不過,我在Chrome中遇到同樣的問題。因此,無論我需要在web.xml中配置不同的東西,允許OPTIONS由於dispatchingservlet或springsecurityfilterchain而做一些它目前無法做的事情,或者如果不是這樣,那麼這個CORS的東西根本無法使用Authorization頭在某些瀏覽器中....我幾乎讀過所有的規格。 – 2013-04-28 21:08:37

回答

1

我們在生產中使用CORS但它只是會在HTML5投訴瀏覽器上工作,我們也遇到了同樣的問題。

我們的客戶端和您的唯一區別是您沒有將withCredentials傳遞給get方法。

像這樣:

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

您也可以設置爲默認:

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

如果沒有這項工作的,試着改變你的CORS servlet來this

+0

我嘗試過使用Credentials,它也沒有工作。此刻,我決定不用CORS。也許我會在1-2年後再次嘗試使用它,直到大多數瀏覽器都支持它,並且所有框架和技術都已正確實施它。不管怎麼說,還是要謝謝你。很高興知道它已經適用於某些人。目前,我可以在一個jar中部署客戶端和服務器部分,並在服務器之間進行負載平衡。 – 2013-09-08 08:19:46