App Domain Level Impersonation

空扰寡人 提交于 2019-12-08 19:06:05

问题


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.

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.

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.

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?


回答1:


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.



来源:https://stackoverflow.com/questions/4837288/app-domain-level-impersonation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!