在我的C#应用程序中,我使用Impersonation来扩展用户的访问权限。为了方便起见,我刚刚添加了一个public static Impersonation对象,该对象在应用程序启动时初始化。
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对象?
发布于 2015-12-29 19:00:52
在Windows中,模拟令牌是为每个线程单独维护的,并且在创建新线程时不会继承。
方法是只模拟需要它的代码路径,正如您在using(...)中所展示的那样。我想说,唯一的区别是,我不会发出.DoWork += { new Impersonation(...) },而是这样做:
var bw = new BackgroundWorker();
bw.DoWork += Impersonated(TOKEN, (s, a) => { /* code */ });另一种方法是,假设BackgroundWorker不是密封的,并且它的OnDoWork()方法是受保护的,那么将继承该类并覆盖OnDoWork()来模拟。然后,您可以这样做:
var bw = new ImpersonatingBackgroundWorker(...)发布于 2015-12-30 02:03:10
正如在blogs.msdn.com中提到的,将以下代码片段添加到App.config文件中就足以让Impersonation跨越线程界限。
<configuration>
<runtime>
<alwaysFlowImpersonationPolicy enabled="true"/>
<legacyImpersonationPolicy enabled="false"/>
</runtime>
</configuration>但是,最佳实践解决方案将只在实际需要的地方使用模拟,而不是全局使用。
https://stackoverflow.com/questions/34509216
复制相似问题