W .NET 4 Klasa ta działa idealnie dla mnie, aby zalogować się na serwerze Windows none poprzez UNC.
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Web.Security;
namespace toolsforimpersonations
{
public class Impersonator
{
#region "Consts"
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
#endregion
#region "External API"
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int CloseHandle(IntPtr hObject);
#endregion
#region "Methods"
//Public Sub PerformImpersonatedTask(ByVal username As String, ByVal domain As String, ByVal password As String, ByVal logonType As Integer, ByVal logonProvider As Integer, ByVal methodToPerform As Action)
public void PerformImpersonatedTask(string username, string domain, string password, int logonType, int logonProvider, Action methodToPerform)
{
IntPtr token = IntPtr.Zero;
if (RevertToSelf()) {
if (LogonUser(username, domain, password, logonType, logonProvider, ref token) != 0) {
dynamic identity = new WindowsIdentity(token);
dynamic impersonationContext = identity.Impersonate();
if (impersonationContext != null) {
methodToPerform.Invoke();
impersonationContext.Undo();
}
// do logging
} else {
}
}
if (token != IntPtr.Zero) {
CloseHandle(token);
}
}
#endregion
}
public class UserImpersonation
{
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_BATCH = 4;
const int LOGON32_LOGON_SERVICE = 5;
const int LOGON32_LOGON_UNLOCK = 7;
const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT35 = 1;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT50 = 3;
WindowsImpersonationContext impersonationContext;
[DllImport("advapi32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int LogonUserA(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern int DuplicateToken(IntPtr ExistingTokenHandle, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern long RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern long CloseHandle(IntPtr handle);
public bool impersonateUser(string userName, string domain, string password)
{
return impersonateValidUser(userName, domain, password);
}
public void undoimpersonateUser()
{
undoImpersonation();
}
private bool impersonateValidUser(string userName, string domain, string password)
{
bool functionReturnValue = false;
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
functionReturnValue = false;
//if (RevertToSelf()) {
if (LogonUserA(userName, domain, password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, ref token) != 0) {
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) {
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if ((impersonationContext != null)) {
functionReturnValue = true;
}
}
}
//}
if (!tokenDuplicate.Equals(IntPtr.Zero)) {
CloseHandle(tokenDuplicate);
}
if (!token.Equals(IntPtr.Zero)) {
CloseHandle(token);
}
return functionReturnValue;
}
private void undoImpersonation()
{
impersonationContext.Undo();
}
}
}
I to jest, jak korzystać ze swojego programowo
UserImpersonation impersonator = new UserImpersonation();
impersonator.impersonateUser("username", "", "password"); //No Domain is required
List<FileInfo> OcDialerlfinfo = null;
OcDialerlfinfo = GetFileList("*", "\\\\10.11.11.122\\shared_folder");
impersonator.undoimpersonateUser();
i przez wzgląd na teście trzeba użyć tego małego funkcję do listy wszystkich plików w katalogu
public static List<FileInfo> GetFileList(string fileSearchPattern, string rootFolderPath)
{
DirectoryInfo rootDir = new DirectoryInfo(rootFolderPath);
List<DirectoryInfo> dirList = new List<DirectoryInfo>(rootDir.GetDirectories("*", SearchOption.AllDirectories));
dirList.Add(rootDir);
List<FileInfo> fileList = new List<FileInfo>();
foreach (DirectoryInfo dir in dirList)
{
fileList.AddRange(dir.GetFiles(fileSearchPattern, SearchOption.TopDirectoryOnly));
}
return fileList;
}
Wygląda to bardzo podobnie do [tego artykułu pomocy firmy Microsoft] (https://support.microsoft.com/en-us/kb/306158#bookmark-4) (dotyczy podszywania się w ASP.NET, mimo że dotyczy aplikacji internetowych jako dobrze). Twój przykładowy kod był bardziej przydatny do ogólnego użytku. – brichins