I hope you can help me.
I am doing some webrequests within my C# 4.0 application which require authentication. I simply use the CredentialsCache.DefaultCredentials. This works great as long as I do not run the functionality in a different thread / task via Task<T>.Factory.StartNew(...). I then get 401 errors. I assume that the credentials are not passed through to child threads?
How can I pass through the credentials to any child tasks / threads?
I assume that you are using impersonation and that the problem is that the credentials are not being flowed into the Task. It's worth checking this point to save a wild goose chase by dumping out the value of
Windows.Identity.GetCurrent().Namein both the initiating code and the Task body and making sure it's what you expect.So given the above, there are a couple of ways that (to put it formally) execution context (or just security context) is not being flowed across threads. The default behaviour is that context is flowed - so something must be affecting that.
1) Something has set
ExecutionContext.SuppressFlow()- you can check this by dumping the value ofExecutionContext.IsFlowSuppressed()inside the task.2) There is a configuration element
<legacyImpersonationPolicy>(conifguration->runtime->legacyImpersonationPolicy) that defaults tofalse. Whenfalse, WindowsIdentity is flowed across asychronous points. Whentrueit is not. This is regardless of the ExecutionContext flow settings. Sotruehere would cause a problem for you. You can check this by dumping the value ofSecurityContext.IsWindowsIdentityFlowSuppressed()is your task. This can also be programmatically set per thread withSecurityContext.SuppressFlowWindowsIdentity().Finally, for completeness, in case you are using unmanaged code there is another setting
<alwaysFlowImpersonationPolicy>that controls how impersonated credentials are flowed in unmanaged scenarios as well; the other settings described only affect managed code.