【问题标题】:BackgroundWorker ignores ImpersonationBackgroundWorker 忽略模拟
【发布时间】:2015-12-29 10:34:35
【问题描述】:

在我的 C# 应用程序中,我使用Impersonation 来扩展用户的访问权限。为方便起见,我只是添加了一个public static Impersonation 对象,该对象在App启动时初始化。

Impersonation 的代码来自this answer on stackoverflow。 到目前为止,在应用程序中执行任何代码都可以正常工作:

someCodeThatNeedsImpersonation(); // Fine
somethingElse();

我现在想将代码移动到BackgroundWorker

BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += (s, a) =>
{
    someCodeThatNeedsImpersonation(); // fails to "see" impersonation
}
bw.RunWorkerCompleted += (s, a) =>
{
    somethingElse();
}
bw.RunWorkerAsync();

这失败了,因为显然在主线程中初始化的Impersonation 句柄没有在BackgroundWorker 中使用。

当然,快速解决方法是

bw.DoWork += (s, a) =>
{
    using ( new Impersonation(...) )
    {
        someCodeThatNeedsImpersonation(); // works, because of bw's own impersonation
    }
}

但我更喜欢在每个 BackgroundWorker 中都不需要新的模拟句柄的解决方案(因为我肯定会忘记一个)。有没有办法共享主线程的static Impersonation对象?

【问题讨论】:

  • 这个是关于ASP.NET的,但是原因和解决方法都是一样的:blogs.msdn.com/b/tom/archive/2008/04/22/…
  • 这也可能有帮助:blog.iamandycohen.com/2012/09/17/…
  • @Dennis 感谢您的链接。第一个链接 (blogs.msdn.com/b/tom/archive/2008/04/22/…) 的方法 2 完美运行。您想将此作为答案发布吗?
  • 好吧,我的答案没有投资,所以,请随意发布答案。此外,它所说的问题是广泛讨论的基础——因为这是桌面应用程序(我假设它是使用BackgroundWorker),这是一个大问题,为什么你需要这么多地方来模拟。所以,你接受的解决方案对我来说看起来不太好,因为,IMO,它隐藏了真正的设计问题。

标签: c# windows backgroundworker impersonation


【解决方案1】:

在 Windows 中,模拟令牌是为每个线程单独维护的,并且在您创建新线程时不会被继承。

要走的路是只模拟需要它的代码路径,正如您已经在 using(...) 中展示的那样。我想说,唯一的区别是,我不会发出.DoWork += { new Impersonation(...) },而是这样做:

var bw = new BackgroundWorker();
bw.DoWork += Impersonated(TOKEN, (s, a) => { /* code */ });

考虑到BackgroundWorker 没有密封,并且它的OnDoWork() 方法受到保护,另一种方法是继承类并覆盖OnDoWork() 来模拟。然后,你可以这样做:

var bw = new ImpersonatingBackgroundWorker(...)

【讨论】:

  • 我完全同意“仅在您需要的地方进行模拟”,但这就是项目发展的方式..
  • 是的,你可以使用更长的模拟,但仍然可以减少重复,就像我的例子一样。注意到BackgroundWorker 不是密封类,并且OnDoWork() 受到保护,您可以做的另一件事是继承和覆盖OnDoWork() 以模拟。然后就做var bw = new ImpersonatingBackgroundWorker(...)。但我个人更喜欢我给出的示例——没有继承——更好。
【解决方案2】:

blogs.msdn.com 所述,将以下sn-p 添加到App.config 文件足以使Impersonation 跨越线程边界。

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

但是,最佳实践解决方案只会在实际需要的地方使用模拟,而不是在全局范围内使用。

【讨论】:

    猜你喜欢
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2014-02-22
    • 1970-01-01
    • 2019-10-27
    • 2020-10-09
    相关资源
    最近更新 更多