"Peniruan identitas" di ruang .NET umumnya berarti menjalankan kode di bawah akun pengguna tertentu. Ini adalah konsep yang agak terpisah daripada mendapatkan akses ke akun pengguna itu melalui nama pengguna dan kata sandi, meskipun kedua gagasan ini sering kali berpasangan. Saya akan menjelaskan keduanya, dan kemudian menjelaskan cara menggunakan pustaka SimpleImpersonation saya , yang menggunakannya secara internal.
Peniruan
API untuk peniruan identitas disediakan di .NET melalui System.Security.Principal
namespace:
Kode yang lebih baru (.NET 4.6+, .NET Core, dll.) Umumnya harus digunakan WindowsIdentity.RunImpersonated
, yang menerima pegangan ke token akun pengguna, dan kemudian Action
atau Func<T>
untuk kode yang akan dieksekusi.
WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
});
atau
var result = WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
return result;
});
Kode yang lebih lama menggunakan WindowsIdentity.Impersonate
metode untuk mengambil WindowsImpersonationContext
objek. Objek ini mengimplementasikan IDisposable
, jadi umumnya harus dipanggil dari using
blok.
using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(tokenHandle))
{
}
Meskipun API ini masih ada di .NET Framework, umumnya harus dihindari, dan tidak tersedia di .NET Core atau .NET Standard.
Mengakses Akun Pengguna
API untuk menggunakan nama pengguna dan kata sandi untuk mendapatkan akses ke akun pengguna di Windows adalah LogonUser
- yang merupakan API asli Win32. Saat ini tidak ada API .NET bawaan untuk memanggilnya, jadi seseorang harus menggunakan 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);
Ini adalah definisi panggilan dasar, namun masih banyak lagi yang perlu dipertimbangkan untuk benar-benar menggunakannya dalam produksi:
- Mendapatkan pegangan dengan pola akses "aman".
- Menutup pegangan asli dengan benar
- Tingkat kepercayaan keamanan akses kode (CAS) (di .NET Framework saja)
- Melewati
SecureString
saat Anda dapat mengambilnya dengan aman melalui penekanan tombol pengguna.
Jumlah kode yang harus ditulis untuk menggambarkan semua ini melampaui apa yang seharusnya ada dalam jawaban StackOverflow, IMHO.
Pendekatan Gabungan dan Lebih Mudah
Alih-alih menulis semua ini sendiri, pertimbangkan untuk menggunakan perpustakaan SimpleImpersonation saya , yang menggabungkan peniruan identitas dan akses pengguna ke dalam satu API. Ini berfungsi dengan baik di basis kode modern dan lama, dengan API sederhana yang sama:
var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, logonType, () =>
{
});
atau
var credentials = new UserCredentials(domain, username, password);
var result = Impersonation.RunAsUser(credentials, logonType, () =>
{
return something;
});
Perhatikan bahwa ini sangat mirip dengan WindowsIdentity.RunImpersonated
API, tetapi tidak mengharuskan Anda mengetahui apa pun tentang pegangan token.
Ini adalah API pada versi 3.0.0. Lihat proyek readme untuk lebih jelasnya. Perhatikan juga bahwa versi pustaka sebelumnya menggunakan API dengan IDisposable
pola, mirip dengan WindowsIdentity.Impersonate
. Versi yang lebih baru jauh lebih aman, dan keduanya masih digunakan secara internal.