39

Windows 認証が有効になっている Web サーバー上で実行される ASP.NET Web API サービスがあります。

HttpClient を使用してサービスからデータをプルする同じ Web サーバー上の別のサイトで実行される MVC4 上に構築されたクライアント サイトがあります。このクライアント サイトは、ID の偽装を有効にして実行され、Windows 認証も使用されます。

Web サーバーは、IIS 7.5 を搭載した Windows Server 2008 R2 です。

私が抱えている課題は、認証プロセスの一環として HttpClient に現在の Windows ユーザーを渡すことです。この方法で HttpClient を構成しました。

var clientHandler = new HttpClientHandler();
clientHandler.UseDefaultCredentials = true;
clientHandler.PreAuthenticate = true;
clientHandler.ClientCertificateOptions = ClientCertificateOption.Automatic;
var httpClient = new HttpClient(clientHandler);

私の理解では、ID の偽装を有効にしてサイトを実行し、この方法でクライアントを構築すると、現在ログインしているユーザーの偽装された ID を使用してクライアントがサービスに対して認証されるはずです。

これは起こっていません。実際、クライアントはまったく認証していないようです。

サービスは Windows 認証を使用するように構成されており、これは完全に機能しているようです。Web ブラウザーでhttp://server/api/shippersにアクセスすると、Windows 認証を求めるプロンプトが表示されます。入力すると、要求されたデータを受け取ります。

IIS ログで、API 要求が認証なしで受信され、401 チャレンジ応答を受信して​​いることがわかります。

これに関するドキュメントはまばらなようです。

何が間違っているのか、またはこのアプリケーションで Windows 認証を使用する別の方法についての洞察が必要です。

ありがとう、クレイグ

4

4 に答える 4

34

HttpClientHandler のソース コード (入手できた最新バージョン) を調べたところ、SendAsync メソッドで次のことがわかります。

// BeginGetResponse/BeginGetRequestStream have a lot of setup work to do before becoming async
// (proxy, dns, connection pooling, etc).  Run these on a separate thread.
// Do not provide a cancellation token; if this helper task could be canceled before starting then 
// nobody would complete the tcs.
Task.Factory.StartNew(startRequest, state);

コード内で SecurityContext.IsWindowsIdentityFlowSuppressed() の値を確認すると、ほとんどの場合 true になります。その結果、StartRequest メソッドは、(偽装されたユーザーの資格情報ではなく) asp.net プロセスの資格情報を使用して新しいスレッドで実行されます。

これには 2 つの方法があります。サーバー aspnet_config.config にアクセスできる場合は、次の設定を行う必要があります (web.config で設定しても効果がないようです)。

<legacyImpersonationPolicy enabled="false"/>
<alwaysFlowImpersonationPolicy enabled="true"/>

aspnet_config.config を変更できない場合は、このシナリオをサポートするために独自の HttpClientHandler を作成する必要があります。

FQDN の使用に関する更新

ここで発生した問題は、「リフレクション攻撃」から保護するように設計された Windows の機能です。これを回避するには、サーバーにアクセスしようとしているマシンで、アクセスしようとしているドメインをホワイトリストに登録する必要があります。以下の手順に従います。

  1. [スタート] --> [ファイル名を指定して実行] --> [regedit] に移動します
  2. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0レジストリ キーを見つけます。
  3. それを右クリックし、Newを選択してからMulti-String Valueを選択します。
  4. タイプBackConnectionHostNames( ENTER )。
  5. 作成したばかりの値を右クリックし、 [変更] を選択します
  6. 値ボックスにローカル コンピューター上のサイトのホスト名を入力し、[ OK ] をクリックします(各ホスト名/FQDN は独自の行にある必要があり、ワイルドカードは使用できません。名前は完全に一致する必要があります)。 .
  7. すべてを保存してマシンを再起動します

この問題に関する完全な KB 記事は、こちらで読むことができます。

于 2012-04-25T08:14:06.997 に答える
10

私もこれと同じ問題を抱えていました。@tpeczek が行った調査のおかげで、次のソリューションを開発しました。HttpClient (スレッドを作成し、要求を非同期に送信する) を使用する代わりに、同じスレッドで要求を発行する WebClient クラスを使用しました。そうすることで、ユーザーの ID を別の ASP.NET アプリケーションから WebAPI に渡すことができます。

明らかな欠点は、これが非同期で機能しないことです。

var wi = (WindowsIdentity)HttpContext.User.Identity;

var wic = wi.Impersonate();
try
{
    var data = JsonConvert.SerializeObject(new
    {
        Property1 = 1,
        Property2 = "blah"
    });

    using (var client = new WebClient { UseDefaultCredentials = true })
    {
        client.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
        client.UploadData("http://url/api/controller", "POST", Encoding.UTF8.GetBytes(data));
    }
}
catch (Exception exc)
{
    // handle exception
}
finally
{
    wic.Undo();
}

注: NuGet パッケージが必要です: Newtonsoft.Json。これは、WebAPI が使用する JSON シリアライザーと同じです。

于 2012-10-01T14:25:51.803 に答える
0

これが機能しない理由は、ダブル ホップ認証が必要だからです。

最初のホップは Web サーバーであり、Windows 認証を使用した偽装を機能させることは問題ありません。ただし、HttpClient または WebClient を使用して別のサーバーに対してユーザーを認証する場合、Web サーバーは、必要な委任を行う権限を持つアカウントで実行する必要があります。

詳細については、次を参照してください:
http://blogs.technet.com/b/askds/archive/2008/06/13/understanding-kerberos-double-hop.aspx

「setspn」コマンドを使用して修正します:
http://www.phishthis.com/2009/10/24/how-to-configure-ad-sql-and-iis-for-two-hop-kerberos-authentication-2/ (これらの操作を実行するには、十分なアクセス権が必要です。)

サーバーが自分の資格情報を好きなように転送することを許可されているとどうなるかを考えてみてください.

于 2013-03-01T14:20:08.860 に答える
0

元の (認証された) ユーザーを偽装するには、Web.config ファイルで次の構成を使用します。

<authentication mode="Windows" />
<identity impersonate="true" />

この構成では、ASP.NET は常に認証されたユーザーを偽装し、すべてのリソース アクセスは認証されたユーザーのセキュリティ コンテキストを使用して実行されます。

于 2016-07-11T08:24:59.203 に答える