IIS6.0のWindowsServer2003で実行されているWSE3.0ベースのWebサービスがあります。Webサービス要求を送信するクライアントユーザーをWebサービスプロセスで偽装したいのですが、サービスはクライアントを偽装していません。
Webアプリケーションには独自のアプリプールがあり、現在、ネットワークサービスIDで実行するように設定されています。Windows Server 2003マシンアカウントは、Active Directoryでの委任が有効になっています(少なくとも私のIT担当者によると)。サービスWSEポリシー(wse3policyCache.config内)は次のようになります。
<policy name="GeneratedServicesPolicy">
<kerberosSecurity establishSecurityContext="false" renewExpiredSecurityContext="true" requireSignatureConfirmation="false" messageProtectionOrder="SignBeforeEncrypt" requireDerivedKeys="true" ttlInSeconds="300">
<protection>
<request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
<response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
<fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
</protection>
</kerberosSecurity>
<requireActionHeader />
</policy>
このサービスのweb.configには、(とりわけ)次のエントリがあります。
<identity impersonate="false"/>
<authentication mode="Windows"/>
アプリケーションに対して匿名アクセスが有効になっています(これは、トランスポートレベルのセキュリティがサービスによって使用されていないため、メッセージレベルが使用されているために必要です)。マシンアカウントには、次のSPNが登録されています。
HOST/RD360-2
HOST/rd360-2.mycompany.com
クライアントのwse3policyCache.configには次のものがあります。
<policy name="KerbClient">
<kerberosSecurity establishSecurityContext="false" renewExpiredSecurityContext="true" requireSignatureConfirmation="false" messageProtectionOrder="SignBeforeEncrypt" requireDerivedKeys="true" ttlInSeconds="300">
<token>
<kerberos targetPrincipal="HOST/rd360-2.mycompany.com" impersonationLevel="Impersonation" />
</token>
<protection>
<request signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
<response signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
<fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody" encryptBody="false" />
</protection>
</kerberosSecurity>
<requireActionHeader />
</policy>
クライアントコードは次のようになります。
static void Main(string[] args)
{
AddFloatsWSWse client = new AddFloatsWSWse();
client.SetPolicy("KerbClient");
double result = client.AddFloats(2.3, 3.2);
Console.WriteLine("Result was: '" + result + "'");
}
ただし、このサービスはクライアントIDを偽装していません。サービスでlog4netを使用してい%usernameますが、ASP.NETトレースログに出力するように要求するNT AUTHORITY\NETWORK SERVICEと、クライアントユーザーIDではなく常にログになります。私が間違っていることはありますか?WSEがなりすましを実行しようとして失敗しているのかどうかを確認できる場所はありますか?イベントログに次のエントリが表示されます(MYDOMAINとMYUSERはここでは隠されています)。
Event Type: Success Audit
Event Source: Security
Event Category: Privilege Use
Event ID: 576
Date: 12/9/2009
Time: 11:07:16 AM
User: MYDOMAIN\MYUSER
Computer: RD360-2
Description:
Special privileges assigned to new logon:
User Name: MYUSER
Domain: MYDOMAIN
Logon ID: (0x0,0x4B410AE)
Privileges: SeSecurityPrivilege
SeBackupPrivilege
SeRestorePrivilege
SeTakeOwnershipPrivilege
SeDebugPrivilege
SeSystemEnvironmentPrivilege
SeLoadDriverPrivilege
SeImpersonatePrivilege
----------------------------------------------------------------------------------
Event Type: Success Audit
Event Source: Security
Event Category: Logon/Logoff
Event ID: 540
Date: 12/9/2009
Time: 11:07:16 AM
User: MYDOMAIN\MYUSER
Computer: RD360-2
Description:
Successful Network Logon:
User Name: MYUSER
Domain: MYDOMAIN
Logon ID: (0x0,0x4B410AE)
Logon Type: 3
Logon Process: Kerberos
Authentication Package: Kerberos
Workstation Name:
Logon GUID: {OBFUSCATED}
Caller User Name: -
Caller Domain: -
Caller Logon ID: -
Caller Process ID: -
Transited Services: -
Source Network Address: -
Source Port: -
そして、私のWSEトレースファイルには次のように表示されます。
<processingStep description="Entering SOAP filter Microsoft.Web.Services3.Design.RequireSoapHeaderAssertion+RequireSoapHeaderFilter" />
<processingStep description="Exited SOAP filter Microsoft.Web.Services3.Design.RequireSoapHeaderAssertion+RequireSoapHeaderFilter" />
<processingStep description="Entering SOAP filter Microsoft.Web.Services3.Design.KerberosAssertion+ServiceInputFilter" />
<processingStep description="Exited SOAP filter Microsoft.Web.Services3.Design.KerberosAssertion+ServiceInputFilter" />
少なくとも、Kerberos拡張機能がKerberosヘッダーを処理していることはわかっています。
編集:次に、私のWebサービスは独自のクライアント通信ライブラリを使用してSSPI / IWAを使用して別のサーバーを呼び出します(この3番目のサーバーをfooサーバーと呼びましょう)。fooサーバーへのこの2回目の呼び出しを行うときに、クライアントのIDを使用するようにします。これは、このクライアント通信ライブラリがfooサーバーのSPNと別のサービスを呼び出しAcquireCredentialsHandleて使用することを意味します。InitializeSecurityContextこの特定のケースでは、fooサーバーは実際にはWSE Webサービスと同じマシンで実行されています(したがって、SPNを使用しています)mycompany/rd260-2)。この2番目のホップは同じマシンに対するものなので、NTLMを使用することを期待しますが、それでもWebサービスクライアントのユーザーIDを偽装する必要がありますね。fooサーバーのログでは、接続を受け入れ、提供されたIWAセキュリティコンテキストを使用し、このセキュリティコンテキストに基づいてrd36-2$、WSE WebサービスがIISで実行されているため、接続しているユーザーがマシンアカウントであることがわかります。ネットワークサービスID(マシンアカウントに関連付けられている)の下。fooサーバーのログで、IWAセキュリティコンテキストを受信した後、最終的にWebサービス要求を送信したユーザーのIDを確認したいと思います。fooサーバーを別のマシンに移動して、それがこれに何らかの関係があるかどうかを確認すると便利ですか?