У меня есть веб-служба на основе WSE 3.0, работающая в Windows Server 2003 под IIS 6.0. Я хочу, чтобы процесс веб-службы выдавал себя за пользователя клиента, который отправляет запрос веб-службы, однако служба не выдает себя за клиента.
Веб-приложение имеет собственный пул приложений, который в настоящее время настроен на запуск под удостоверением сетевой службы. Учетная запись компьютера Windows Server 2003 была включена для делегирования в Active Directory (по крайней мере, по словам моего ИТ-специалиста). Политика службы 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 + "'");
}
Однако служба не выдает себя за личность моего клиента. Я использую log4net в службе, и когда я прошу распечатать %username
в журнале трассировки ASP.NET, это всегда NT AUTHORITY\NETWORK SERVICE
, а не идентификатор пользователя клиента. Есть ли что-то, что я делаю неправильно? Есть ли где-нибудь, где я могу посмотреть, пытается ли 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.
Редактировать: мой веб-сервис затем использует проприетарную клиентскую коммуникационную библиотеку для вызова другого сервера с помощью SSPI/IWA (назовем этот третий сервер сервером foo). Я хочу, чтобы он использовал идентификатор клиента, когда он делает этот второй вызов на сервер foo. Это означает, что эта клиентская коммуникационная библиотека вызывает AcquireCredentialsHandle
и InitializeSecurityContext
, используя SPN сервера foo и другой службы. В данном конкретном случае сервер foo фактически работает на том же компьютере, что и веб-служба WSE (поэтому он использует имя участника-службы mycompany/rd260-2
). Поскольку этот второй прыжок относится к той же машине, я ожидаю, что он будет использовать NTLM, но он все равно должен олицетворять удостоверение пользователя моего клиента веб-службы, не так ли? В журналах сервера foo я вижу, что он принимает соединение, использует предоставленный контекст безопасности IWA и сообщает мне, что на основе этого контекста безопасности подключающимся пользователем является rd36-2$
, который является учетной записью компьютера, поскольку веб-служба WSE работает в IIS под идентификатором сетевой службы (который, в свою очередь, связан с учетной записью компьютера). В журналах сервера foo после получения контекста безопасности IWA я в конечном итоге хочу увидеть личность пользователя, отправившего запрос веб-службы. Было бы полезно переместить сервер foo на другую машину, чтобы посмотреть, имеет ли это какое-то отношение к этому?