开始编辑
我使用dwLogonType = 9(LOGON32_LOGON_NEW_CREDENTIALS)和dwLogonProvider = 3(LOGON32_PROVIDER_WINNT50)
结束修改
我正在尝试以USER_A身份登录时模拟USER_B。模拟的目的是访问网络共享上的资源(以防万一,类似于\ host_b \ folder $ \ subfolder_1 \ subfolder_2 \ file_b.JPG)
USER_A无权写入file_b.JPG。 USER_B(我通过使用USER_B凭据登录host_b进行了测试)。
但是,在模仿USER_B之后,当写入file_b.JPG时,我会遇到System.UnauthorizedAccessException
异常。
我不知道会出现什么问题,特别是在其他情况下,假冒行为完美无瑕。
我用来模拟的代码如下,通过创建Impersonator
的新实例
namespace Util.Impersonation
{
public class Impersonator : IDisposable
{
private static readonly ILog logger = LogManager.GetLogger(typeof(Impersonator));
public Impersonator(
string userName,
string domainName,
string password)
{
ImpersonateValidUser(userName, domainName, password);
}
public void Dispose()
{
UndoImpersonation();
}
[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);
private void ImpersonateValidUser(
string userName,
string domain,
string password)
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
logger.Info($"Trying to impersonate {userName}@{domain}.");
try
{
if (RevertToSelf())
{
if (LogonUser(userName,
domain,
password,
Settings.Impersonation_dwLogonType,
Settings.Impersonation_dwLogonProvider,
ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
logger.Info($"Succesfully impersonating {userName}@{domain}.");
}
else
{
LogErrorAndThrow();
}
}
else
{
LogErrorAndThrow();
}
}
else
{
LogErrorAndThrow();
}
}
finally
{
if (token != IntPtr.Zero)
{
CloseHandle(token);
}
if (tokenDuplicate != IntPtr.Zero)
{
CloseHandle(tokenDuplicate);
}
}
}
private void LogErrorAndThrow()
{
var exception = new Win32Exception(Marshal.GetLastWin32Error());
logger.ErrorFormat("There was a problem during impersonation: {0}", exception);
throw exception;
}
private void UndoImpersonation()
{
if (impersonationContext != null)
{
logger.Info($"Trying to undo impersonation.");
impersonationContext.Undo();
logger.Info($"Succesfully undo impersonation.");
}
}
private WindowsImpersonationContext impersonationContext = null;
}
}
先谢谢!