2017-02-27 12 views
0

私はMVCアプリケーションと、関連するWeb APIプロジェクトを持っています。これらは両方ともIIS上のリモートサーバーでホストされています。それらは同じアプリケーションプールを共有します。 MVCアプリケーションからWeb APIを呼び出そうとするたびに、403エラーが発生します。これは、HttpClientHandlerによって渡された不正な資格情報から来ているようです。私は MVCアプリケーションからWeb APIを呼び出してWindows統合認証を使用する

UseDefaultCredentials = true 

を持っていると私は

Credentials = CredentialCache.DefaultNetworkCredentials 

を設定しようとしたが、これらのいずれもAPIリクエストが通過することができます。

私のADユーザー名/パスワードを使用するようにアプリケーションプールを設定すると、すべてのAPI要求が通過することができ、また、PostmanからAPIを直接呼び出してデータを正しく返します。

私の前提は、IIS AppPool [プール名]がリクエストで転送され、適切な資格情報が渡されないということです。とにかくこれを回避するAPIを非セキュアにすることはありません(つまり、いくつかのドメイングループだけがアクセスできるはずです)。

私が言うのはそのハードコードを見ることなくMVCアプリケーション

public async Task<HttpResponseMessage> CreateIncident(Incident model) 
    { 
     using (var client = new HttpClient(new HttpClientHandler { UseDefaultCredentials = true })) 
     { 
      var newIncident = new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json"); 
      var response = await client.PostAsync(hostUri, newIncident); 
      return response; 
     } 
    } 
+0

プロキシを経由していますか? – joshmcode

+0

いいえ、これはすべて内部サーバー上でホストされ、すべての呼び出しはそのサーバーを介して排他的に行われます。プロキシはありません。私が言ったように、私のコンピュータからのPostmanとAPIへの直接呼び出しは通過しますが、.NET Coreは要求を偽装することはできません。私は最近、他の誰かがこれを最近ヒットして、 .NETコアでは古くなっている6カ月齢のものよりも優れています。 –

答えて

0

あなたはこのGitHubのディスカッションページで既に認証(Windowsの場合)ユーザーを偽装する方法を見つけることができます:https://github.com/aspnet/Home/issues/1805

ilancは、底部に向かっリンクで本当に良いのデモを持っています。

1

からAPIを作ってるんだコールの例。 Credentialsパラメータを設定せずに試しましたか?私は、フィドラーを実行し、MVCアプリケーションと郵便配達員によって送信されたリクエストを比較します。

+0

私はFiddlerからの結果を調べました。 Postmanは統合Windows認証のために交渉をしていないため、サーバーは自動的に自分のログイン資格情報を決定しています。 MVCアプリケーションに関しては、リクエストとともに交渉認証を送信しています。その結果、401が返されます。そのため、APIがIIS AppPool情報を取得し、資格情報として送信していると考えています。私はまた、質問のサンプルコードのビットを投げた。 –

+0

UseDefaultCredentials = trueを削除しようとしましたか? –

+0

さて、それは全く影響を与えていないようです。 PreAuth = falseとCredentialsを何かに設定してみました。デビッドのソリューションと一緒に行くだけで、アプリケーションが完全にコアにならない可能性があります。 –

3

これ以上の情報がなければ、確かに言うのは難しいですが、問題はおそらくダブルホップ認証のためです。

  1. (ウェブサイトの場合はブラウザ)クライアントアプリケーション は、MVCアプリケーションは、その後に沿って、認証をパスしようとするクライアントがサーバ(MVCアプリケーション)
  2. 認証を送信し、ユーザーを認証しますWebサービスへ

私は同様のタスクを実行する必要があるとき、私はHttpClientを動作させることができませんでした。私はこの質問から多くの提案された解決策、How to get HttpClient to pass credentials along with the request?を試しました。特に、ブラックスパイの答えのこの部分は、なぜ説明されましたか:

あなたがしようとしているのは、NTLMがIDを次のサーバに転送することです。ローカルリソースへのアクセス権しか与えない偽装。

私は(この場合はウェブAPIからファイルを、ダウンロードする)MVCアプリケーションでこのようなもので(必要なターゲットと.NETフレームワークとの)Webクライアントを使用して終了:

private async Task GetFileAsync(Identity identity, string serviceAddress, Stream stream) 
{ 
    var windowsIdentity = Identity as WindowsIdentity; 

    if (windowsIdentity == null) 
    { 
     throw new InvalidOperationException("Identity not a valid windows identity."); 
    } 

    using (windowsIdentity.Impersonate()) 
    { 
     using (var client = new WebClient { UseDefaultCredentials = true }) 
     { 
      var fileData = await client.DownloadDataTaskAsync(serviceAddress); 
      await stream.WriteAsync(fileData, 0, fileData.Length); 
      stream.Seek(0, SeekOrigin.Begin); 
     } 
    } 
} 

ながら完全なフレームワークを対象とする要件は、これが.NET Coreソリューションであることを防ぎますが、それ以降追加されたように見えます。

Add WebClient to new System.Net.WebClient contract

このPRポートシステム。Net.WebClientからcorefxへコードは主にデスクトップから取得され、その後は少し書式で整理されます。唯一の主要なコードの書き換えは、数百行の複雑なAPMコールバックベースのコードを削除し、それをいくつかのコア非同期メソッドに置き換えることでした。まだ多くのクリーンアップができますが、機能的にはこれで十分です。

+0

私はこの解決策を見ました(そして、ダブルホップについてはあまりにも多くのことを読んでいます)が、Webクライアントはまだコアにあるとは思わない。彼らはリポジトリにそれをマージしましたが、私はそれがどのRCやプレビューにも含まれていないと言える限り、Visual Studioでそれを参照することはできません。私が読んだもう一つのStack Overflowスレッドにはもはや機能しなかった時代遅れの解決策があったため、誰かが偽装のためのより最新の実装を持つことを望んでいました。私は.NET Frameworkを指し示すことを嫌っていますが、これもまた下になるかもしれません。ありがとう! –

+0

デイヴィッド、私は最終的に私が探していた解決策を見つけました(そうです...少し時間がかかりました)。ここでGitHubの問題のディスカッションを見つけることができます。ユーザーのilancは、ディスカッションの最後にサンプルのレポ方法へのリンクを投稿しました。 https://github.com/aspnet/Home/issues/1805 –

関連する問題