Dobrý den, Jak přesně funguje CredentialCache nevím, ale předpokládám že funguje jen pro protokoly SMTP, HTTP nebo FTP, ale ne pro Windows autentizaci. Pokud voláte Directory.GetDirectories apod., tak se ke vzdálenému prostředku v síti přistupuje pod právy Windows identity, pod kterou běží aktuální process (lze jí zjistit pomoci WindowsIdentity.GetCurrent().Name), a autentizace tam bude buď Kerberos nebo NTLM (ale ne basic, digest apod.). Pokud chcete nějaký kód volat pod jinou identitou, než je aktuální identita běžícího procesu, obecný mechanismus, který to umožňuje je impersonace (impersonation). Před vlastní impersonací musíte danou Windows identitu získat tj. provést její autentizaci např. pomoci jména a hesla, což se musí udělat pomoci Windows API funkcí LogonUser. Kód bude vypadat takto:
[SuppressUnmanagedCodeSecurityAttribute()]
private static class SafeNativeMethods
{
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword,
Int32 dwLogonType, Int32 dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
internal static extern int CloseHandle(IntPtr handle);
}
private static WindowsIdentity LogonUser(string userName, string password, string domainName)
{
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT40 = 2; //NTLM
const int LOGON32_PROVIDER_WINNT50 = 3; //Negotiate (NTLM, Kerberos or other SSP (Security Support Provider))
const int LOGON32_LOGON_INTERACTIVE = 2; //This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_BATCH = 4;
const int LOGON32_LOGON_SERVICE = 5;
const int LOGON32_LOGON_UNLOCK = 7;
IntPtr tokenHandle = IntPtr.Zero;
int returnValue = SafeNativeMethods.LogonUser(userName, domainName, password,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);
if (returnValue == 0)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
var identity = new WindowsIdentity(tokenHandle);
if (tokenHandle != IntPtr.Zero)
{
SafeNativeMethods.CloseHandle(tokenHandle);
}
return identity;
}
static void Main()
{
var identity = LogonUser("UserName", "Password", null);
using (identity.Impersonate())
{
string[] theFolders = Directory.GetDirectories(@"\\192.168.1.19\system");
//TODO: Use theFolders
}
}
Možná, že pro tento scénář nebude potřeba LogonUser volat s módem LOGON32_LOGON_INTERACTIVE ale bude stačit pouze LOGON32_LOGON_NETWORK, vyzkoušejte.
|