10

私は、Spring MVCを使用してREST APIバックエンドを構築し、Spring Securityを使用して基本認証で保護しました。JQueryクロスドメイン基本認証コール

JavascriptクライアントからREST APIへのクロスドメインajax呼び出しを行いたいと思います。私はGET呼び出しに限定されたくないのでJSONPを使いたくありません。私はCORSを使用し、私はサーバー側に適切なヘッダーを配置しています。

私のREST APIがドメインlocalhost:8087にあり、クライアントがlocalhost:8086(クロスドメインコール)にあるとします。私のJavascriptのクライアントで

は、私はjQueryを使ってAjaxの呼び出しを行います。

<script> 
     $.ajax ({ 
      url: "http://localhost:8087/SpringMVC/users/user1", 
      beforeSend: function (xhr) { xhr.setRequestHeader ("Authorization", "Basic xxxxxxxxxxxx"); }, 
      success: function(val) { console.log(val); alert("success" + val); }, 
      error: function(val) { console.log(val); alert("error" + val); } 
     }); 
</script> 

私の問題は、jQueryのHTTPリクエストでAuthorizationヘッダを送信しないと私は理由がわからないということです。私はbeforeSendメソッドでそれを行うので、私は理解しません、それはHTTP要求の内側にあるはずです。結果:401エラーが発生しました。

同じドメインlocalhost:8087からスクリプトを試すと、もうドメイン間ではないので問題はありません。

どうすれば可能ですか?

私のスクリプトは単なるテストにすぎません。私はユーザー名/パスワードをクライアント側に置くつもりはありません。しかし、基本的なauthで保護されたREST APIにajax呼び出しを行う方法をテストしたいと思います。私は私のユーザー名/パスワードを保護するためにサーバー側で送信する必要があると思いますが、REST APIは私にクッキーを送り返し、私はREST APIへの次のajax呼び出しのためにユーザー名/パスワードを渡す必要はありません。私は正しい?

私はREST APIをChrome Advanced RESTクライアントでテストしましたが、そのように機能しています。最初のリクエストでは、私は認証ヘッダーを渡す必要があります。その後、それは必要ではありません。それは私のjavascript Webクライアントでも同様に動作するはずですか? Node.JSをBackboneとともに使用して構築したいと考えています。

ありがとうございます。

EDIT2:実際にはCORSブラウザの問題と思われます。私は、サーバー側にOPTIONSメソッドのヘッダーAccess-Control-Allow-Methodsを追加しました。これはChrome上で動作します。私はもはやエラーなしでJSON応答にアクセスできます。しかし、私は依然として次のリクエストに承認ヘッダーを使用する必要があります。 jQueryに送信されたCookieを使用するように指示する方法

と私はFirefoxを11にしようとしたとき、私はJSONレスポンスへのアクセス全くないと私はエラーを持っている:

"NetworkError: 401 Non-Autorisé - http://localhost:8087/SpringMVC/users/user1" 
+0

ユーザー名/パスワードをbase64でエンコードしていますか? –

+0

はい、実際のユーザー名:パスワードの代わりにxxxxxxxxを入力します。 – rico

答えて

8

どうやら、ChromeとFirefoxはクロスドメインは少し異なる要求扱います。 クロスドメイン要求を行う前に、HTTP OPTIONSメソッドで「プリフライト」要求と呼ばれる処理を行います。 ChromeとFirefoxの違いは、ChromeがクレデンシャルとともにAuthorizationヘッダーも送信するのに対して、Firefoxはそうではないことです。

次に、Spring Securityの設定上の問題が残ります。私のurl/users/*はOPTIONSを含むすべてのHTTPメソッドに対して保護されています。 Firefoxの場合、Authorizationヘッダーが送信されないので、私の要求は承認されません。私の安全なurl/users/*をGETメソッドだけに制限すると、Firefoxでは完全に機能します。だから私は、私の春のセキュリティの設定でのみそれを追加する必要がありました:私はOPTIONSを除き、インターセプト、URL内に固定する他の方法を追加することができ、または私はHTTPを制限することができます。その後

<intercept-url pattern="https://stackoverflow.com/users/*" access="isAuthenticated()" method="GET"/> 

、私は選択肢を持っています私のSpring MVCコントローラでGETメソッドを呼び出すと、Javadocに従ってOPTIONS呼び出しを処理することさえできます。私は第2の解決策を選んだ。しかし、誰かがFirefoxのようにChromeのような資格情報を送るように強制する解決策を見つけたら、それは素晴らしいだろう。私はこれを選ぶだろう。

2

だろうリコが提示春のセキュリティ設定シナリオのための別のオプション:

<http ... use-expressions="true"> 
    <intercept-url pattern="https://stackoverflow.com/users/*" access="permitAll" method="OPTIONS"/> 
    <intercept-url pattern="https://stackoverflow.com/users/*" access="isAuthenticated()"/> 
    ... 
</http> 

のHTTP OPTIONS要求は常に認証を通過し、他のHTTPメソッドはしません。

use-expressions XML属性がの場合、<http>の要素に設定されていることに注意してください。春のセキュリティは、<intercept-url>要素のaccess属性が春ELを含むことを期待しますpermitAllにisAuthenticated()のように、を表現。