我需要将该方法反向移植到.NET 4.0
public static class SomeClass
{
public static void Run(ContextBody callback)
{
System.Security.Principal.WindowsIdentity.RunImpersonated(Microsoft.Win32.SafeHandles.SafeAccessTokenHandle.InvalidHandle, delegate
{
callback();
});
}
}
现在相应的.NET 4.0代码将是
using (System.Security.Principal.WindowsIdentity wi =
new System.Security.Principal.WindowsIdentity(System.IntPtr.Zero))
{
using (System.Security.Principal.WindowsImpersonationContext context = wi.Impersonate())
{
var cuid = System.Security.Principal.WindowsIdentity.GetCurrent();
System.Console.WriteLine(cuid.User);
}
}
但是,这不起作用,因为当我使用IntPtr.Zero(aka SafeAccessTokenHandle.InvalidHandle)时,它会引发Null引用异常。
所以我需要找到进程所有者的WindowsIdentity,例如
using (System.Security.Principal.WindowsIdentity wi =
GetWindowsIdentity(@"domain\username"))
{
using (System.Security.Principal.WindowsImpersonationContext context = wi.Impersonate())
{
// I need to find the original WindowsIdentity here.
// GetCurrent only returns the impersonated id
var cuid = System.Security.Principal.WindowsIdentity.GetCurrent();
System.Console.WriteLine(cuid.User);
}
}
其中GetWindowsIdentity如下
private static WindowsIdentity GetWindowsIdentity(string userName)
{
using (var user =
UserPrincipal.FindByIdentity(
UserPrincipal.Current.Context,
IdentityType.SamAccountName,
userName
) ??
UserPrincipal.FindByIdentity(
UserPrincipal.Current.Context,
IdentityType.UserPrincipalName,
userName
))
{
return user == null
? null
: new WindowsIdentity(user.UserPrincipalName);
}
}
但是,我尝试过的所有方法(Environment.Username,ManagementObjectSearcher,静态类内的WindowsIdentity的静态实例,WinAPI调用,将true或false传递给GetCurrent,通过AD的processid获取用户)均无效。
此外,我无法在程序开始的某个地方保存原始用户ID,因为这是在我不控制的主程序使用的库中。
如何在模拟上下文中获取原始用户的WindowsIdentity?
或如何取消模拟.NET 4.0?
注意:
此方法(运行)的目的是运行在模拟上下文中运行的未内部模拟的某些代码。
我再次强调:仅.NET 4.0