任务/线程内的 CredentialsCache.DefaultCredentials

发布于 2024-12-09 19:52:36 字数 246 浏览 0 评论 0原文

我希望你能帮助我。

我正在我的 C# 4.0 应用程序中执行一些需要身份验证的网络请求。我只是使用CredentialsCache.DefaultCredentials。只要我不通过 Task.Factory.StartNew(...) 在不同的线程/任务中运行该功能,这种方法就非常有效。然后我收到 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

江城子 2024-12-16 19:52:36

我假设您正在使用模拟,问题是凭据没有流入任务。值得检查这一点,通过在启动代码和任务主体中转储 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 of ExecutionContext.IsFlowSuppressed() inside the task.

2) There is a configuration element <legacyImpersonationPolicy> (conifguration->runtime->legacyImpersonationPolicy) that defaults to false. When false, WindowsIdentity is flowed across asychronous points. When true it is not. This is regardless of the ExecutionContext flow settings. So true here would cause a problem for you. You can check this by dumping the value of SecurityContext.IsWindowsIdentityFlowSuppressed() is your task. This can also be programmatically set per thread with SecurityContext.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.

断爱 2024-12-16 19:52:36

万一其他人遇到这个问题......我的有点不同。我的 WCF 服务作为 REST 服务和 SOAP 公开,安全上下文来自 System.Web.HttpContext.Current 或 System.ServiceModel.OperationContext.Current。我的 DAL 使用这些上下文之一通过检查 HttpContext.Current.User.Identity 或 OperationContext.Current.ClaimsPrincipal.Identity 来识别当前用户。

因此,对于我的情况,我必须将这两个上下文保存在并行 foreach 外部的变量中,然后将它们设置在并行内部以保存值。这似乎成功了。经过一些修改,相同的概念也适用于其他 TPL 情况。

var httpcontext = System.Web.HttpContext.Current;
var opcontext = System.ServiceModel.OperationContext.Current;
Parallel.ForEach(types, (p) =>
{
    System.Web.HttpContext.Current = httpcontext;
    System.ServiceModel.OperationContext.Current = opcontext;

    // DO YOUR PARALLEL PROCESSING HERE
});

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.

var httpcontext = System.Web.HttpContext.Current;
var opcontext = System.ServiceModel.OperationContext.Current;
Parallel.ForEach(types, (p) =>
{
    System.Web.HttpContext.Current = httpcontext;
    System.ServiceModel.OperationContext.Current = opcontext;

    // DO YOUR PARALLEL PROCESSING HERE
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文