«Олицетворение» в пространстве .NET обычно означает запуск кода под определенной учетной записью пользователя. Это несколько отдельная концепция, чем получение доступа к этой учетной записи пользователя через имя пользователя и пароль, хотя эти две идеи часто объединяются. Я опишу их обоих, а затем объясню, как использовать мою библиотеку SimpleImpersonation , которая использует их для внутреннего использования.
Олицетворение
API для олицетворения предоставляются в .NET через пространство имен System.Security.Principal
:
Более новый код (.NET 4.6+, .NET Core и т. Д.) Обычно должен использовать WindowsIdentity.RunImpersonated
, который принимает дескриптор для токена учетной записи пользователя, а затем либо Action
или Func<T>
для выполнения кода.
WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
// do whatever you want as this user.
});
или
var result = WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
// do whatever you want as this user.
return result;
});
В более старом коде для извлечения объекта WindowsImpersonationContext
использовался метод WindowsIdentity.Impersonate
. Этот объект реализует IDisposable
, поэтому обычно его следует вызывать из блока using
.
using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(tokenHandle))
{
// do whatever you want as this user.
}
Хотя этот 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, ИМХО.
Комбинированный и простой подход
Вместо того, чтобы писать все это самостоятельно, рассмотрите возможность использования моей библиотеки SimpleImpersonation , которая объединяет олицетворение и доступ пользователей в единый API. Он хорошо работает как в современных, так и в старых базах кода, с тем же простым API:
var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, logonType, () =>
{
// do whatever you want as this user.
});
или
var credentials = new UserCredentials(domain, username, password);
var result = Impersonation.RunAsUser(credentials, logonType, () =>
{
// do whatever you want as this user.
return something;
});
Обратите внимание, что он очень похож на WindowsIdentity.RunImpersonated
API, но не требует, чтобы вы ничего не знали об маркерах токенов.
Это API версии 3.0.0. Смотрите readme проекта для более подробной информации. Также обратите внимание, что в предыдущей версии библиотеки использовался API с шаблоном IDisposable
, аналогичным WindowsIdentity.Impersonate
. Более новая версия намного безопаснее, и обе по-прежнему используются внутри компании.