I have been reading The .NET Developer's Guide to Windows Security and it mentioned that as of .NET 1.1 a calling threads principal is not automatically propagated to a thread spun off by the ThreadPool using the QueueUserWorkItem method; it has to be manually set. Looks like this has changed as of .NET 2.0 as the following test shows. It automatically propagates when the ThreadPool initiates a call with a thread in the pool, when using the APM and manually creating threads:

 

// Set the executing threads principle\identity
Thread.CurrentPrincipal = new GenericPrincipal(
    new GenericIdentity("Louis De Broglie"), null);

Action<string> writeInfo = new Action<string>((n) =>
    Console.WriteLine(string.Format("{0} - {1}", n,
    Thread.CurrentPrincipal.Identity.Name)));

// Test the executing thread
writeInfo.Invoke("Main Thread");

// Test queueing a worker item on the thread pool
ThreadPool.QueueUserWorkItem(x => 
    writeInfo.Invoke("Thread Pool Initiated Thread"));

// Test making an async call
Action asyncCall = new Action(() => 
    writeInfo.Invoke("Async Initiated Thread"));

asyncCall.BeginInvoke(ar => asyncCall.EndInvoke(ar), null);

// Test manually creating a thread
new Thread(() => 
    {
        writeInfo.Invoke("Manually Created Thread");

        // Set a new principal
        Thread.CurrentPrincipal = new GenericPrincipal(
            new GenericIdentity("Erwin Schrödinger"), null);

        writeInfo.Invoke("Manually Created Thread, new identity");

        // Test queueing a worker item on the thread pool
        ThreadPool.QueueUserWorkItem(x =>
            writeInfo.Invoke("Thread Pool Initiated Thread from a new Thread"));

        // Test making an async call
        asyncCall = new Action(() =>
            writeInfo.Invoke("Async Initiated Thread from a new Thread"));

        asyncCall.BeginInvoke(ar => asyncCall.EndInvoke(ar), null);

        // Test manually creating a thread from a thread
        new Thread(() => 
            writeInfo.Invoke("Manually Created Thread from a new Thread")
            ).Start();
    }).Start();

Console.ReadKey();
 

image