应用域级模拟 [英] App Domain Level Impersonation

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

问题描述

我正在开发一个应用程序,需要将插件加载到单独的子应用程序域中.只有一个插件加载到一个子应用程序域中.每个插件都需要不同的 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\Privileged1Authority\Privileged2.Authority\Privileged1Authority\Privileged2 分别拥有对数据库 Database1Database2 的所有必要访问权限,而 Authority\Privileged2em>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.AppDomain.SetThreadPrincipal 方法传递 System.Security.Principal.WindowsPrincipal 实例.该实例是从从重复的用户令牌创建的 System.Security.Principal.WindowsIdentity 实例创建的(请参阅 http://support.microsoft.com/kb/306158).我省略了对 WindowsIdentity.Impersonate 方法的调用,因为我在创建 WINdowsPrincipal 实例时处于默认应用程序域中.

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天全站免登陆