«Олицетворение» в пространстве .NET обычно означает запуск кода под определенной учетной записью пользователя. Это несколько отдельная концепция, чем получение доступа к этой учетной записи через имя пользователя и пароль, хотя эти две идеи часто сочетаются друг с другом. Я опишу их оба, а затем объясню, как использовать мою библиотеку SimpleImpersonation , которая использует их внутри.
Выдача себя за другое лицо
API-интерфейсы для олицетворения предоставляются в .NET через System.Security.Principal
пространство имен:
Как правило, следует использовать WindowsIdentity.RunImpersonated
более новый код (.NET 4.6+, .NET Core и т. Д.) , Который принимает дескриптор токена учетной записи пользователя, а затем либо Action
или Func<T>
для кода для выполнения.
WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
});
или
var result = WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
return result;
});
В более старом коде этот WindowsIdentity.Impersonate
метод использовался для извлечения WindowsImpersonationContext
объекта. Этот объект реализует IDisposable
, поэтому обычно его следует вызывать из using
блока.
using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(tokenHandle))
{
}
Хотя этот API все еще существует в .NET Framework, его обычно следует избегать, и он недоступен в .NET Core или .NET Standard.
Доступ к учетной записи пользователя
API для использования имени пользователя и пароля для получения доступа к учетной записи пользователя в Windows LogonUser
- это собственный API Win32. В настоящее время нет встроенного .NET API для его вызова, поэтому необходимо прибегнуть к P / Invoke.
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
Это базовое определение вызова, однако для его реального использования в производственной среде необходимо учитывать гораздо больше:
- Получение ручки с «безопасным» доступом.
- Правильное закрытие родных дескрипторов
- Уровни доверия безопасности доступа для кода (CAS) (только в .NET Framework)
- Проходит,
SecureString
когда вы можете безопасно собрать его с помощью нажатия клавиш пользователя.
Объем кода, который нужно написать, чтобы проиллюстрировать все это, выходит за рамки того, что должно быть в ответе StackOverflow, IMHO.
Комбинированный и более простой подход
Вместо того, чтобы писать все это самостоятельно, рассмотрите возможность использования моей библиотеки SimpleImpersonation , которая объединяет олицетворение и доступ пользователей в один API. Он хорошо работает как в современной, так и в старой кодовой базе с одним и тем же простым API:
var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, logonType, () =>
{
});
или
var credentials = new UserCredentials(domain, username, password);
var result = Impersonation.RunAsUser(credentials, logonType, () =>
{
return something;
});
Обратите внимание, что он очень похож на WindowsIdentity.RunImpersonated
API, но не требует от вас каких-либо знаний о дескрипторах токенов.
Это API версии 3.0.0. Подробнее см. В файле readme. Также обратите внимание, что предыдущая версия библиотеки использовала API с IDisposable
шаблоном, похожим на WindowsIdentity.Impersonate
. Более новая версия намного безопаснее, и обе они по-прежнему используются внутри компании.