Der Windows-Identitätswechsel löst dieses Problem, indem die Anmeldeinformationen zum Abrufen eines Benutzer-Tokens verwendet werden. Mit diesem Token kann dann eine WindowsIdentity abgerufen werden, die dann zum Generieren eines Identitätswechselkontexts verwendet wird. Innerhalb dieses Kontextbereichs können Sie dann auf das Dateisystem als den imitierten Benutzer zugreifen.
Natürlich müssen Sie den Benutzernamen und das Kennwort speichern, damit dieser Ansatz funktioniert.
Zunächst definieren Sie die Windows-APIs benötigt, um ein Benutzertoken von Windows zu erhalten:
internal class WindowsAPI
{
public const int LOGON32_PROVIDER_DEFAULT = 0;
public const int LOGON32_LOGON_INTERACTIVE = 2;
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername,
String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken
);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
}
Dann diese APIs verwenden, um ein Windows aquire:
private WindowsIdentity GetIdentity(string userName, string password)
{
_userToken = IntPtr.Zero;
if (!WindowsAPI.LogonUser(
userName,
AbbGrainDomain,
password,
WindowsAPI.LOGON32_LOGON_INTERACTIVE, WindowsAPI.LOGON32_PROVIDER_DEFAULT,
ref _userToken
))
{
int errorCode = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(errorCode);
}
return new WindowsIdentity(_userToken);
}
Und schließlich nutzen diese Identität zu einen Identitätswechsel Kontext erzeugen:
public List<string> GetDirectories(string searchPath)
{
using (WindowsImpersonationContext wic = GetIdentity().Impersonate())
{
var directories = new List<string>();
var di = new DirectoryInfo(searchPath);
directories.AddRange(di.GetDirectories().Select(d => d.FullName));
return directories;
}
}
Schließlich ist es wichtig zu bereinigen, die Windows-Handle mit dem IDisposable-Muster, mit dem gespeicherten _userToken:
if (_userToken != IntPtr.Zero)
WindowsAPI.CloseHandle(_userToken);
Ich denke, Sie finden es IPrincipal –