【发布时间】:2011-06-17 18:16:17
【问题描述】:
我正在开发一个需要将插件加载到单独的子应用程序域的应用程序。只有一个插件加载到一个子应用程序域中。每个插件都需要不同的 Windows 标识,并且这些标识与默认(父)应用程序域中使用的 Windows 标识不同。每个插件都会加载其一个或多个子插件。
例如默认应用程序域的标识是Authority\Limited(Authority 是域名或机器名)。两个插件被加载到两个子应用程序域中。加载插件的身份分别为Authority\Privileged1和Authority\Privileged2。 Authority\Privileged1 和 Authority\Privileged2 分别拥有对数据库 Database1 和 Database2 的所有必要访问权限,而 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