任务/线程内的 CredentialsCache.DefaultCredentials
我希望你能帮助我。
我正在我的 C# 4.0 应用程序中执行一些需要身份验证的网络请求。我只是使用CredentialsCache.DefaultCredentials
。只要我不通过 Task
在不同的线程/任务中运行该功能,这种方法就非常有效。然后我收到 401 错误。我假设凭据没有传递给子线程?
如何将凭据传递给任何子任务/线程?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我假设您正在使用模拟,问题是凭据没有流入任务。值得检查这一点,通过在启动代码和任务主体中转储 Windows.Identity.GetCurrent().Name 的值并确保它符合您的预期,从而避免白费力气。
因此,鉴于上述情况,有几种方法(正式地说)执行上下文(或只是安全上下文)不会跨线程流动。默认行为是上下文是流动的 - 所以一定有什么东西在影响它。
1) 某些内容已设置
ExecutionContext.SuppressFlow()
- 您可以通过转储任务内ExecutionContext.IsFlowSuppressed()
的值来检查这一点。2)有一个配置元素
(configuration->runtime->legacyImpersonationPolicy)默认为false
。当false
时,WindowsIdentity在异步点之间流动。当true
时,它不是。这与 ExecutionContext 流设置无关。所以这里的true
会给你带来问题。您可以通过转储SecurityContext.IsWindowsIdentityFlowSuppressed()
的值来检查这一点是您的任务。这也可以使用SecurityContext.SuppressFlowWindowsIdentity()
以编程方式针对每个线程进行设置。最后,为了完整起见,如果您使用非托管代码,还有另一个设置
也可以控制模拟凭据在非托管场景中的流动方式;描述的其他设置仅影响托管代码。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().Name
in 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. Whentrue
it is not. This is regardless of the ExecutionContext flow settings. Sotrue
here 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.万一其他人遇到这个问题......我的有点不同。我的 WCF 服务作为 REST 服务和 SOAP 公开,安全上下文来自 System.Web.HttpContext.Current 或 System.ServiceModel.OperationContext.Current。我的 DAL 使用这些上下文之一通过检查 HttpContext.Current.User.Identity 或 OperationContext.Current.ClaimsPrincipal.Identity 来识别当前用户。
因此,对于我的情况,我必须将这两个上下文保存在并行 foreach 外部的变量中,然后将它们设置在并行内部以保存值。这似乎成功了。经过一些修改,相同的概念也适用于其他 TPL 情况。
In case someone else comes across this issue... mine was a little different. My WCF service is exposed as a REST service as well as a SOAP, with the security context coming from either System.Web.HttpContext.Current or System.ServiceModel.OperationContext.Current. My DAL uses one of those contexts to identify the current user by checking HttpContext.Current.User.Identity or OperationContext.Current.ClaimsPrincipal.Identity.
So for my case, I had to save those two contexts in variables outside of the parallel foreach and then set them inside the parallel to the saved values. That seemed to do the trick. The same concept could work for other TPL situations with some modifications.