Учитывая имя пользователя и пароль, как я выдаю себя за этого пользователя и запустил какой-то код в качестве этого пользователя.Как олицетворять пользователя в управляемом коде?
И сумел я имею в виду без pinvokes или dllimports
Учитывая имя пользователя и пароль, как я выдаю себя за этого пользователя и запустил какой-то код в качестве этого пользователя.Как олицетворять пользователя в управляемом коде?
И сумел я имею в виду без pinvokes или dllimports
Это класс-оболочка мы создали, который работал на нескольких различных платформах Windows:
public class Impersonator
{
// constants from winbase.h
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_LOGON_NETWORK = 3;
public const int LOGON32_LOGON_BATCH = 4;
public const int LOGON32_LOGON_SERVICE = 5;
public const int LOGON32_LOGON_UNLOCK = 7;
public const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
public const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
public const int LOGON32_PROVIDER_DEFAULT = 0;
public const int LOGON32_PROVIDER_WINNT35 = 1;
public const int LOGON32_PROVIDER_WINNT40 = 2;
public const int LOGON32_PROVIDER_WINNT50 = 3;
[DllImport("advapi32.dll", SetLastError=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)]
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);
public static WindowsImpersonationContext LogOn(string userName, string password)
{
return LogOn(userName, password, "");
}
public static WindowsImpersonationContext LogOn(string userName, string password, string domain)
{
WindowsIdentity tempWindowsIdentity;
WindowsImpersonationContext impersonationContext;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if(RevertToSelf())
{
if (LogonUserA(userName, domain, password, LOGON32_LOGON_NEW_CREDENTIALS,
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 impersonationContext;
}
}
}
else
{
var win32 = new Win32Exception(Marshal.GetLastWin32Error());
//throw new Exception(string.Format("{0}, Domain:{1}, User:{2}, Password:{3}",
// win32.Message, domain, userName, password));
throw new Exception(win32.Message);
}
}
if(token!= IntPtr.Zero)
CloseHandle(token);
if(tokenDuplicate!=IntPtr.Zero)
CloseHandle(tokenDuplicate);
return null; // Failed to impersonate
}
public static bool LogOff(WindowsImpersonationContext context)
{
bool result = false;
try
{
if (context != null)
{
context.Undo();
result = true;
}
}
catch
{
result = false;
}
return result;
}
}
Там в аналогичный вопрос с большим ответом here.
Посмотрите WindowsImpersonationContext
для более определенной информации (также есть еще один отличный пример кода там)
было интересно, если бы это можно было сделать без каких-либо dllimports – Simon
Если это веб-сайт ASP.NET, то да, это можно сделать, установив элемент '
@Simon: олицетворение также полезно во время установки или для запуска приложения «как» кто-то другой, например, администратор. – AMissico
См ImpersonationHelper
из Is it possible to safely get a SecureString value from VB .NET?. Код является готовым к производству и надежным.
Он поддерживает IDisposable
, содержит метод RunAs
(что бесценно), пароли обрабатываются как SecureString
и другие полезные полезные свойства. Я также предоставил код для тестирования как для класса ImpersonationHelper
, так и для устранения неполадок, и их методы SecureString
extenstion, которые пригождаются.
Я варил до двух простых методов:
public bool ImpersonateValidUser(String userName, String domain, String password)
public void UndoImpersonation()
Вы можете directlyh копировать/вставить класс ниже, и использовать его в вашем проекте:
class ImpersonationContext
{
[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);
public const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
public const int LOGON32_PROVIDER_WINNT50 = 3;
WindowsImpersonationContext impersonationContext;
public bool ImpersonateValidUser(String userName, String domain, String password)
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
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)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
public void UndoImpersonation()
{
impersonationContext.Undo();
}
}
Конечно, это сводится к двум методам. не имеет обработки ошибок, и если ошибка не возникает, не освобождает созданные ею дескрипторы. – AMissico
Все примеры, которые я видел, не могут ake учитывает тот факт, что тип входа не является единственным размером, подходящим для всего решения.
Например, это будет работать только в том случае, если пользователь, у которого вы выдаете себя за прав, имеет разрешение на вход в целевую систему. Не всегда при доступе к удаленному ящику SQL Server. LOGON32_LOGON_INTERACTIVE
NetworkClearText является единственным, который работает последовательно для использования с соединениями SQL Server. - Нет четкого текста, это не означает, что он передаёт учетные данные небезопасным образом.
Когда на рабочей группе и вы должны олицетворять пользователя домена, NewCredentials - это тот, который работает. (не тестировалось с подключением SQL Server)
отлично поработал John. Спасибо. – GR7
Добро пожаловать, silverCORE –
Где вы находите значения LOGON32_PROVIDER_x? –