English 中文(简体)
How do I get a WSE 3.0 web service to impersonate my client s identity?
原标题:

I have a WSE 3.0 based web service running in Windows Server 2003 under IIS 6.0. I want the web service process to impersonate the client user that sends the web service request, however the service is not impersonating the client.

The web application has its own app pool, which is currently set to run under the Network Service identity. The Windows Server 2003 machine account has been enabled for delegation in Active Directory (at least according to my IT guy). The service WSE policy (in wse3policyCache.config) looks like this:

<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>

The service has the following entries (among others) in its web.config:

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

Anonymous access is enabled for the application (this is required since transport-level security is not used by the service, message-leve is). The machine account has the following SPN s registered:

HOST/RD360-2
HOST/rd360-2.mycompany.com

The client has the following in its 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>

The client code looks like this:

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 + " ");
}

The service is not impersonating my client identity, though. I am using log4net in the service, and when I ask it to print out the %username into the ASP.NET trace log, it is always NT AUTHORITYNETWORK SERVICE and not the client user id. Is there anything I m doing wrong? Is there somewhere I can look to see if WSE is even trying to perform the impersonation and failing? I do see the following entries in my event log (MYDOMAIN and MYUSER are obscured here):

Event Type: Success Audit
Event Source:   Security
Event Category: Privilege Use 
Event ID:   576
Date:       12/9/2009
Time:       11:07:16 AM
User:       MYDOMAINMYUSER
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:       MYDOMAINMYUSER
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:    -

And in my WSE trace file I do see:

<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" />

so at least I know the Kerberos extensions are processing my Kerberos headers.

Edit: My webservice then uses a proprietary client communication library to call into another server using SSPI/IWA (let s call this third server a foo server). I want it to use the client s identity when it makes this second call into the foo server. This means that this client communication library calls AcquireCredentialsHandle and InitializeSecurityContext using the SPN of the foo server and a different service. In this particular case, the foo server is actually running on the same machine as the WSE web service (so it s using the SPN mycompany/rd260-2). Since this second hop is to the same machine, I would expect this to use NTLM, but it still should impersonate my web service client s user identity, shouldn t it? In the logs of the foo server, I see that it accepts the connection, uses the IWA security context provided and tells me that based on this security context, the connecting user is rd36-2$ which is the machine account since the WSE web service is running in IIS under the Network Service identity (which is in turn associated to the machine account). In the logs of the foo server, after it receives the IWA security context, I ultimately want to see the identity of the user who submitted the web service request. Would it be useful to move the foo server to a different machine to see if that has some bearing on this?

最佳回答

The Kerberos token used with WSE 3 is a message-level security mechanism and only authenticates the client. It does not actually change the security context as in IWA, so you won t notice anything different in the trace log as such. In order to actually impersonate the client, you have to:

  • Enable impersonation on the security token with impersonationLevel="Impersonation" on the <kerberos> element (which you ve already done); and
  • Have your WebMethod create a WindowsImpersonationContext based on the token s identity.

Example:

WindowsIdentity identity =
    (WindowsIdentity)RequestSoapContext.Current.IdentityToken.Identity;
WindowsImpersonationContext impersonationContext = null;
try
{
    impersonationContext = identity.Impersonate();

    // Perform your work here
    // ...
}
finally
{
    if (impersonationContext != null)
    {
        impersonationContext.Undo();
    }
}
问题回答

As far I can understand the situation is when you re trying to make the second hop the Kerberos ticket is dropped. In double hop scenario s the Kerberos Ticket will be dropped at the second hop.

Your authentication will fail after that and will not switch to NTLM.





相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签