【发布时间】:2016-03-23 16:58:44
【问题描述】:
我正在尝试在 Impersonation 下使用 Process.Start(),我已经 google 了几天,我遇到的大多数答案都是在 ASP.net 下,但我正在为 Window Application 开发,所以我遇到了困难找到根本原因。
这是我的模拟代码
private void impersonateValidUser(string userName, string domain, string password)
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if ( LogonUser( userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 )
{
tempWindowsIdentity = new WindowsIdentity( tokenDuplicate );
mImpersonationContext = tempWindowsIdentity.Impersonate();
}
}
}
我正在尝试通过我的程序打开文档(无.exe,例如.txt、.doc)
using (new Impersonator(DomainUserID, Domain, Password))
Process.Start(filePath);
到目前为止,我能够使用模拟用户检测目录/文件,假设我当前的登录用户不可见,因为我没有授予它访问权限。但是每当我尝试打开文档时,都会出错
System.ComponentModel.Win32Exception (0x80004005): Access is denied
如果我错了,请纠正我,所以在这种情况下,我不应该将 UseShellExecute 设置为 false(以及带有用户名和密码输入的 processStartInfo 吗?),因为它用于可执行文件(?),我确实也遇到了 CreateProcessAsUser 函数,而且这个函数似乎也不适用于我的情况,从我读到的示例中,它也适用于 .exe 文件。
如果有人能启发我,将不胜感激。
更新:模拟类
public class Impersonator : IDisposable
{
#region P/Invoke
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int LogonUser( string lpszUserName,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int DuplicateToken( IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
#endregion
#region Constants
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
#endregion
#region Attributes
private WindowsImpersonationContext mImpersonationContext = null;
#endregion
#region Public methods.
public Impersonator( string userName, string domainName, string password)
{
impersonateValidUser(userName, domainName, password);
}
#endregion
#region IDisposable member.
public void Dispose()
{
undoImpersonation();
}
#endregion
#region Private member.
private void impersonateValidUser(string userName, string domain, string password)
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
try
{
if ( RevertToSelf() )
{
if ( LogonUser( userName, domain, password,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 )
{
tempWindowsIdentity = new WindowsIdentity( tokenDuplicate );
mImpersonationContext = tempWindowsIdentity.Impersonate();
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
finally
{
if ( token != IntPtr.Zero )
{
CloseHandle( token );
}
if ( tokenDuplicate != IntPtr.Zero )
{
CloseHandle( tokenDuplicate );
}
}
}
/// <summary>
/// Reverts the impersonation.
/// </summary>
private void undoImpersonation()
{
if ( mImpersonationContext != null )
{
mImpersonationContext.Undo();
}
}
#endregion
}
【问题讨论】:
-
你能把你的 Impersonator 类的所有代码贴出来
-
嗨,谢谢回复,我在问题中更新了我的课程
-
对不起,我没有看到你的更新,我会尝试比较这两个实现。
-
对不起,我刚才弄乱了格式,我刚刚更新了问题。我会测试你发布的代码并稍后在这里更新,干杯:-D
-
它需要您 PInvoke RunProcessAsUser,这要实现这一点要困难得多。尝试 ping Microsoft 以获得咨询服务。
标签: c# impersonation