我知道有很多关于Impersonate的问题,但我找不到正确的答案或找到解决问题的方法。
我正在尝试从运行我的代码的WM上的服务器复制文件。 我已经使用了这个“WindowsIdentityImpersonateMethod”,它可以为大多数人提供良好的工作。
对于我来说,当我想在我的WM上模仿另一个用户时,工作正常。 但是对于在不同Domaine上的服务器上模拟用户,它不起作用。
using System;
using System.IO;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using Microsoft.Win32.SafeHandles;
namespace WindowsIdentityImpersonateMethodWithDelegate
{
public enum LogonType
{
LOGON32_LOGON_INTERACTIVE = 2,
LOGON32_LOGON_NETWORK = 3,
LOGON32_LOGON_BATCH = 4,
LOGON32_LOGON_SERVICE = 5,
LOGON32_LOGON_UNLOCK = 7,
LOGON32_LOGON_NETWORK_CLEARTEXT = 8, // Win2K or higher
LOGON32_LOGON_NEW_CREDENTIALS = 9 // Win2K or higher
};
public enum LogonProvider
{
LOGON32_PROVIDER_DEFAULT = 0,
LOGON32_PROVIDER_WINNT35 = 1,
LOGON32_PROVIDER_WINNT40 = 2,
LOGON32_PROVIDER_WINNT50 = 3
};
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTokenHandle()
: base(true)
{
}
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
public class ImpersonationHelper
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private extern static bool CloseHandle(IntPtr handle);
/// <summary>
/// Impersonates the specified domain name.
/// </summary>
/// <param name="domainName">Name of the domain.</param>
/// <param name="userName">Name of the user.</param>
/// <param name="userPassword">The user password.</param>
/// <param name="actionToExecute">The action to execute.</param>
/// <exception cref="System.ComponentModel.Win32Exception"></exception>
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public void Impersonate(string domainName, string userName, string userPassword, Action actionToExecute)
{
SafeTokenHandle safeTokenHandle;
try
{
const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(userName, domainName, userPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle); //returns false
//bool returnValue1 = LogonUser(userName, domainName, userPassword, 9, 3,
//out safeTokenHandle); // return always true, even when userName ist wrong
if (returnValue == false)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
using (safeTokenHandle)
{
// Use the token handle returned by LogonUser.
using (WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
{
using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
{
bool test = File.Exists(@"\\10.29.14.05\c$\test.xml"); //always false, file is acessible from start->run
bool test5 = Directory.Exists(@"\\10.99.10.25\c$\"); //false
bool test1 = File.Exists(@"C:\test.xml"); //false
Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name); //always local user
actionToExecute();
}
}
}
}
catch (Exception ex)
{
throw;
}
}
}
}
我的用户拥有所有权利,它就是这样的。
string domain = "10.29.14.05";
string user = @"testtest\user1";
string password = "password!";
正如您在代码中看到的,我使用了两种不同的Logntype和LogonProviders。
bool returnValue = LogonUser(userName, domainName, userPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle); //returns false
当我使用这一行时。 我得到一个例外 System.ComponnentModel-Win32Exception “用户名或密码不正确”
bool returnValue1 = LogonUser(userName, domainName, userPassword, 9, 3, out safeTokenHandle);
当我使用此行时,即使userName错误,LogonUser方法也始终返回TRUE。
此行始终是本地用户
Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name);
三个测试变量总是返回false
bool test = File.Exists(@"\\10.29.14.05\c$\test.xml"); //always false, file is accessible from start->run
bool test5 = Directory.Exists(@"\\10.99.10.25\c$\"); //false
bool test1 = File.Exists(@"C:\test.xml"); //false
如何解决这个问题? 方向搜索或任何东西将来自帮助,谢谢。