应用程序域级别的模拟 [英] App Domain Level Impersonation

查看:87
本文介绍了应用程序域级别的模拟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am developing an application that needs to load plug-ins into separate child app domains. Only one plug-in is loaded into one child app domain. Each plug-in requires different Windows identity and those identities are different from the Windows identity used in default (parent) app domain. Each plug-in loads one or more of its child plug-ins.

例如默认应用程序域的身份为 Authority \ Limited (身份是域名或计算机名称).两个插件被加载到两个子应用程序域中.加载的插件的身份为 Authority \ Privileged1 Authority \ Privileged2 . Authority \ Privileged1 Authority \ Privileged2 分别具有对数据库 Database1 Database2 的所有必要访问权限,而 Authority \ Limited 无权访问上述任何数据库.

E.g. Identity of default app domain is Authority\Limited (Authority is either domain name or machine name). Two plug-ins are loaded into two child app domains. The identities of the loaded plug-ins are Authority\Privileged1 and Authority\Privileged2. Authority\Privileged1 and Authority\Privileged2 have all necessary access to databases Database1 and Database2, respectively, whereas the Authority\Limited does not have access to any of aforementioned databases.

创建子应用程序域时,我通过 System.Security.Principal.WindowsPrincipal 实例调用 System.AppDomain.SetThreadPrincipal 方法.该实例是从 System.Security.Principal.WindowsIdentity 实例创建的,该实例是由重复的用户令牌创建的(请参见

When creating child app domain, I call System.AppDomain.SetThreadPrincipal method passing System.Security.Principal.WindowsPrincipal instance. The instance was created from System.Security.Principal.WindowsIdentity instance created from duplicated user token (see http://support.microsoft.com/kb/306158). I have omitted the call to WindowsIdentity.Impersonate method since I am in default app domain while creating the WIndowsPrincipal instance.

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

I expected that setting the app domains thread principal would be sufficient for the loaded plug-ins to successfully log in to their respective databases and execute some T-SQL statements. To my surprise, the value returned by WindowsIdentity.GetCurrent() method is used when opening a connection to database. The value returned by the method is either process identity or impersonated identity.

由于进程标识没有使用数据库所需的权限,因此不可接受.因此,模拟必须发挥作用.但是,模拟只能在子应用程序域中进行. 每个插件都公开了用于执行插件加载和卸载的方法.我知道我必须在这些方法的开头执行模拟,并在这些方法结束时撤消模拟. 但是,还必须对子应用程序域中产生的所有线程进行模拟.由于每个插件会加载其子插件中的一个或多个,并且每个插件可能会产生一个或多个线程,因此必须在许多地方执行模拟,这看起来非常混乱.

Since the process identity does not have permissions necessary to work with the databases, it is not acceptable. Therefore, impersonation must come to play. However, impersonation must take place only in child app domains. Each plug-in exposes methods used to perform loading and unloading of the plug-in. I understand that I have to perform impersonation at the start and undo the impersonation at the end of those methods. However, the impersonation must be done for all threads spawned in the child app domains as well. Since each plug-in loads one or more of its child plug-ins and each plug-in might spawn one or more threads, the impersonation would have to be performed in many places, and that looks very messy.

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

Is it possible to perform impersonation only once so that affects all threads that are spawned in the child app domains?

推荐答案

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

No you can't do that - impersonation is per thread and the same thread can have code from several AppDomain on a call stack. This is especially true for plugin systems where main code (from some main AppDomain) calls plugin's logic in separate AppDomain.

本质上,您必须在调用插件之前先进行模拟,并在完成后还原.请注意,如果插件将线程池用于其自身的操作,则它将需要正确地模拟.

Essentially you have to impersonate before calling plugin and revert when you are done. Note that if plugin uses threadpool for its own operations than it will need to impersonate properly.

这篇关于应用程序域级别的模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆