sqlwcftask-parallel-libraryiis-5

TPL Task in WCF service fails to use correct IIS security Credentials (SQL Connection)


I have a WCF service method that calls a SQL stored proc. I'm developing using IIS 5 (can't do much about that, II6/7 not available)

To get some gains, I'm doing a number of async calls to this stored proc by putting the call into a c# TPL Task.

When run as a Task, I'm getting an SQL Exception... "Login failed. The login is from an untrusted domain and cannot be used with Windows authentication"

However, If I run the exact same process without using a Task, I have no problems with SQL connection

It would appear to me that the credentials for the IIS Virtual folder (WCF) are not being delegated to the Task? Any ideas how I can specificy credentials for the TPL Task thread, ie to use the same as the parent etc ?

I am using Windows Authentication (sspi), and impersonation to be able to connect to the seperate SQL box.

Your help appreciated.


Solution

  • You have two choices.

    1) Opt your entire application into always flowing the identity using:

    <runtime>
        <alwaysFlowImpersonationPolicy enabled="true"/>
    </runtime>
    

    This has a side effect of overhead and the danger of accidentally executing some unintended code with the priviledges of the currently calling user rather than the application identity. I would personally avoid this and go with #2 where you explicitly opt-in.

    2) Capture the WindowsIdentity before setting up your TPL tasks and explicitly impersonate where you need to make the calls using Impersonate + WindowsImpersonationContext:

    public void SomeWCFOperation()
    {
        WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent();
    
        Task.Factory.StartNew(() =>
        {
             // some unpriviledged code here
    
    
             using(WindowsImpersonationContext impersonationContext = currentIdentity.Impersonate())
             {
                // this code will execute with the priviledges of the caller
             }
    
             // some more unpriviledged code here
        });  
    }