【问题标题】:App Domain Level Impersonation应用域级别模拟
【发布时间】:2011-06-17 18:16:17
【问题描述】:

我正在开发一个需要将插件加载到单独的子应用程序域的应用程序。只有一个插件加载到一个子应用程序域中。每个插件都需要不同的 Windows 标识,并且这些标识与默认(父)应用程序域中使用的 Windows 标识不同。每个插件都会加载其一个或多个子插件。

例如默认应用程序域的标识是Authority\Limited(Authority 是域名或机器名)。两个插件被加载到两个子应用程序域中。加载插件的身份分别为Authority\Privileged1Authority\Privileged2Authority\Privileged1Authority\Privileged2 分别拥有对数据库 Database1Database2 的所有必要访问权限,而 em>Authority\Limited 无权访问上述任何数据库。

在创建子应用程序域时,我调用 System.AppDomain.SetThreadPrincipal 方法传递 System.Security.Principal.WindowsPrincipal 实例。该实例是从由重复的用户令牌创建的 System.Security.Principal.WindowsIdentity 实例创建的(请参阅http://support.microsoft.com/kb/306158)。我省略了对 WindowsIdentity.Impersonate 方法的调用,因为我在创建 WIndowsPrincipal 实例时处于默认应用程序域中。

我希望设置应用程序域线程主体足以使加载的插件成功登录到各自的数据库并执行一些 T-SQL 语句。令我惊讶的是,在打开与数据库的连接时使用了 WindowsIdentity.GetCurrent() 方法返回的值。该方法返回的值要么是进程身份,要么是模拟身份。

由于进程身份没有使用数据库所需的权限,因此这是不可接受的。因此,必须冒充。但是,模拟必须仅在子应用程序域中进行。 每个插件都公开了用于执行插件加载和卸载的方法。我知道我必须在开始时执行模拟并在这些方法结束时撤消模拟。 但是,也必须对子应用程序域中产生的所有线程进行模拟。由于每个插件都会加载一个或多个子插件,并且每个插件都可能产生一个或多个线程,因此必须在很多地方执行模拟,这看起来很混乱。

是否可以只执行一次模拟,从而影响在子应用程序域中生成的所有线程?

【问题讨论】:

  • 您可以考虑使用子进程而不是子域并在所需帐户下运行这些进程。显式设置远程处理会使事情变得有点复杂,但大概您已经有了适合远程处理类型的 API。
  • 应用程序已经支持以任意身份运行子进程。但是,它必须支持子应用程序域的相同内容。谢谢。

标签: c# identity appdomain impersonation principal


【解决方案1】:

不,您不能这样做 - 模拟是每个线程的,同一个线程可以在调用堆栈上拥有来自多个 AppDomain 的代码。对于主代码(来自一些主 AppDomain)在单独的 AppDomain 中调用插件逻辑的插件系统尤其如此。

本质上,您必须在调用插件之前模拟并在完成后恢复。请注意,如果插件使用线程池进行自己的操作,则需要正确模拟。

【讨论】:

  • 谢谢,阿列克谢。是否有事件表明已分配线程来执行应用程序域中的某些代码并且线程已完成代码执行?如果有这样的事件,我可以订阅它们,并尊重地在一个地方进行模拟和还原。
  • 我不知道。我从来不需要这个,我会阅读远程处理并查看 System.Runtime.Remoting 命名空间以找出答案。
  • 很公平。感谢您的建议。
猜你喜欢
  • 1970-01-01
  • 2012-08-29
  • 1970-01-01
  • 2017-08-10
  • 1970-01-01
  • 2020-07-14
  • 2010-10-16
  • 2012-07-20
  • 1970-01-01
相关资源
最近更新 更多