このテーマについては以前にも投稿したことがありますが、1 年間別のことをやっていた後、再び苦境に陥ることができました。シナリオの簡単な概要と、物事を機能させるための現在の試みについて説明します。
- ホスト上の HTML、JS などをホストする IIS Web サーバー: iis.mycompany.com ( fooと呼ばれる)
- ホスト上の Windows サービスを介してホストされる WCF RESTful Web サービス: wcf.mycompany.com ( barと呼ばれる)
fooから提供される Javascript は、 barの WCF サービスに対してRESTful ajax 呼び出し (GET
またはPOST
アクションに応じて) を行うことによって機能します。これらは同じホスト上にないため、明らかにクロス ドメイン呼び出しです。
Javascript は jQuery (1.7.2) フレームワークを使用して DOM を操作し、 barへのajax呼び出しを実行POSTS
します。JSON
GETS
JSON
Barには、セキュリティ モードとして使用して構成された WCF サービスがTransportCredentialOnly
あり、トランスポート クライアントの資格情報の種類はNTLM
であるため、認証されたユーザーのみがサービスにアクセスできます。
WCF の拡張機能を使用して、 bar のWCF サービスに CORS サポートが追加されました。
http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx
追加のヘッダーを追加し、多数のインターネット記事に基づいて、投稿に既に含まれているものをいくつか変更しました。
property.Headers.Add("Access-Control-Allow-Headers", "Accept, Content-Type");
property.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
property.Headers.Add("Access-Control-Max-Age", "172800");
property.Headers.Add("Access-Control-Allow-Origin", "http://iis.mycompany.com");
property.Headers.Add("Access-Control-Allow-Credentials", "true");
property.Headers.Add("Content-type", "application/json");
Access-Control-Allow-Origin
CORS の有効化に関する情報を提供するサイトは、応答ヘッダーを に設定する必要があることを示唆してい"*"
ますが、次の設定を使用して jQuery ajax 呼び出しを行うため、これは不可能です。
$.ajaxSetup({
cache: "false",
crossDomain: true,
xhrFields: {
withCredentials: true
}
});
結局のところ、ajax 呼び出しで"*"
使用している場合、受け入れられたオリジンには使用できません。"withCredentials"
https://developer.mozilla.org/en/http_access_control
「重要な注意: 認証された要求に応答するとき、サーバーはドメインを指定する必要があり、ワイルドカードは使用できません。」
現在、開発ラボでは、IIS (foo) サーバー URL への要求をハードコーディングできるため、これは問題ではありません。
POST
主な問題は、リクエストの試行にあるようです (GET
上記の構成を使用して動作しています)。POST
ブラウザがプロセスを試行すると、最初にヘッダーをサーバーに送信して、後続の投稿OPTIONS
を許可するように要求します。OPTIONS
これは、CORS サポート WCF 拡張機能で構成したヘッダーが返されることを確認したいところですが、そこまで到達していません。応答が"401 Unauthorized"として返される前に、これは NTLM を要求するトランスポート セキュリティ バインディング構成に関係していると思いますが、よくわかりません。
また、私はこれについてあまり経験がありませんが、クロス ドメイン リクエストを実行する場合とは対照的に、コンテンツ タイプのPOST
使用に関する情報はあまり見たことがありません。application/json
text/plain
人々がおそらく唯一の真の解決策として提案することを私は知っていJSONP
ます。私はさまざまなアプローチに反対していません。実際、他の人が後でこの質問を読むのに役立つので、ベストプラクティスを提案することをお勧めします ただし、代替案を提示する前に、質問への回答を試みてください。
貢献してくれた人には、事前に感謝します。
ペテスキー:)
アップデート:
Chrome (20.xx) ではOPTIONS
、サーバーからヘッダー応答を取得するために NTLM をネゴシエートしないという問題は発生していないようですが、Firefox (13.0.1) では問題が発生しています。
また、誰かが既に Firefox フォーラムにバグを投稿していることに気付きました。以下に情報を追加しました:
http://bugzilla.mozilla.org/show_bug.cgi?id=751552
bugzilla サイトでこのバグを修正するために投票してください!
次のコードを使用すると、ネットワーク トレースを監視して、Firefox が失敗し、Chrome が正常に動作していることを確認できます。
var url = "http://myWebServiceServer/InstantMessagingService/chat/message/send";
var data = '{ "remoteUserUri" : "sip:foo.bar@mydomain.com", "message" : "This is my message" }';
var request = new XMLHttpRequest();
request.open("POST", url, true);
request.withCredentials = true;
request.setRequestHeader("Content-Type", "application/json");
request.send(data);
console.log(request);
別のメモとして、IE8 はクロス ドメイン呼び出しをサポートしておらず、XMLHttpRequest
独自の魔法のXDomainRequest
オブジェクトを優先しているため、IE8 と世界のケースを処理するようにクライアント側のコードを変更する作業が必要です。(ありがとうIE8)。
/me は、Mozilla が Firefox のバグを修正するよう指を交差させます。
更新 2:
掘り下げた結果、IE8XDomainRequest
を使用して、NTLM をネゴシエートする必要があるクロス ドメイン リクエストを作成できないようです。これは基本的に、Web ブラウザーの制限により、WCF バインディングのセキュリティを使用できないことを意味します。
「リクエストとともに認証または Cookie は送信されません」
ですから、今のところこれを行っていると思います..独自のカスタム トークン認証を作成し、それを Cookie で WCF サービスに渡す必要があるようです。 IE8 の場合はPOST
、JSON を使用します。ServiceSecurityContext.Current.WindowsIdentity
WCF サービスは、データの復号化を処理し、以前 NTLM 認証でアクセスしていた代わりにそれを使用する必要があります。