Я работал над проектом на C # (.net4).Project в значительной степени позволяет людям загружать файлы со своего локального компьютера в общий сетевой ресурс.
Общий сетевой ресурс защищен.Он доступен только пользователю с именем «proxy», который создается в активном каталоге.
Я провел некоторое исследование и обнаружил этот класс, который использовал для олицетворения.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;
namespace Datacom.CorporateSys.Utilities
{
public class ImpersonateUser
{
[DllImport("advapi32.dll")]
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)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
WindowsImpersonationContext impersonationContext;
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
private string p;
private string p_2;
private string p_3;
private String UserName
{
set;
get;
}
private String Domain
{
set;
get;
}
private String Password
{
set;
get;
}
/// <summary>
/// Impersonates the user.
/// </summary>
/// <param name="userName">Name of the user.</param>
/// <param name="domain">The domain.</param>
/// <param name="password">The password.</param>
public ImpersonateUser(string userName, string domain, string password)
{
UserName = userName;
Domain = domain;
Password = password;
}
/// <summary>
/// Impersonates the valid user.
/// </summary>
/// <returns></returns>
public bool impersonateValidUser()
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUserA(UserName, Domain, Password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
/// <summary>
/// Undoes the impersonation.
/// </summary>
public void undoImpersonation()
{
impersonationContext.Undo();
}
}
}
Примечание: сПамять Я думаю, что нашел это в качестве примера на MSDN.
Вот как я пытаюсь переместить файл с локального пути в сеть
if (imp.impersonateValidUser())
{
System.IO.File.Copy(local_file, server_file, true);
imp.undoImpersonation();
}
else
{
throw new Exception("Unable to impersonate for uploading file.");
}
И это работает!У меня никогда не было проблем с подражанием - исключение никогда не бросалось.Он отлично работает и загружает файлы на сервер.Однако, когда я начал тестировать немного больше, я обнаружил, что если прокси-пользователь не вошел в систему на сервере (обычно я открываю вход в RDS и завершаю работу - не выходя из системы).
Я получаю другое исключение - исключение сетевого пути не найдено, и это происходит только тогда, когда я только что перезапустил сервер и «прокси» не вошел в систему.
Мой первыйМысль заключалась в том, что с классом олицетворения что-то не так, однако он отлично подражает, когда работает (т. е. файлы владеют прокси-пользователем).Тогда я подумал, что, возможно, «прокси» должен войти в систему, чтобы ОС могла использовать свои разрешения для фактического доступа к \ server \ uploads
.Обратите внимание: у меня нет контроля над сервером.Сервер win2k8 с установленным рабочим столом (иначе я не могу получить доступ к любым сетевым расположениям).
Спасибо!