If you try to make an asynchronous call, you will notice that the thread that executes the call doesn't run under the same account as the thread that called it, assuming you are using impersonation.

There are a number of ways to change this if you would like to have it use the same identity.

Method 1

The Thread used by BeginInvoke doesn't copy the windowsIdentity from the calling thread. You have to impersonate the new thread manually:
Before calling BeginInvoke save the current identity into a variable:

Dim identity as WindowsIdentity
identity = System.Security.Principal.WindowsIdentity.GetCurrent()

Inside the asynchronously called method use this variable and execute:

identity.Impersonate

From that point on the asynchronous call uses the same privileges than the calling thread and it should not be a problem to execute the callback.

Method 2

If the thread making the asynchronous call creates the thread being used, and you are using .NET 2.0 or later, you can set the following in the config file.  For ASP.NET, use the aspnet.config file:

<configuration>
<runtime>
<alwaysFlowImpersonationPolicy enabled="true"/>
<legacyImpersonationPolicy enabled="false"/>
</runtime>
</configuration>

Method 3

Another way to handle this is if you have an account that you want the asynchronous call to run under, you can impersonate that account, run what you need to, and then undo the impersonation.  The following code will do that:

using System.Security.Principal;
...
WindowsIdentity wi = new WindowsIdentity(userName@fullyqualifieddomainName);
WindowsImpersonationContext ctx = null;
try
{
  ctx = wi.Impersonate();
  // Thread is now impersonating
}
catch
{
  // Prevent exceptions propagating.
}
finally
{
  // Ensure impersonation is reverted
  ctx.Undo();
}

Additional Information

For more information, you can check out these links

kick it on DotNetKicks.com