"การเลียนแบบ" ในพื้นที่. NET โดยทั่วไปหมายถึงการเรียกใช้รหัสภายใต้บัญชีผู้ใช้ที่ระบุ มันเป็นแนวคิดที่ค่อนข้างแยกต่างหากจากการเข้าถึงบัญชีผู้ใช้นั้นผ่านชื่อผู้ใช้และรหัสผ่านแม้ว่าแนวคิดทั้งสองนี้จะจับคู่กันบ่อยครั้ง ฉันจะอธิบายพวกเขาทั้งสองและจากนั้นอธิบายวิธีใช้ไลบรารีSimpleImpersonationของฉันซึ่งใช้ภายใน
การแสดงบทบาท
API สำหรับการรับบทบาทมีไว้ใน. NET ผ่านSystem.Security.Principal
เนมสเปซ:
รหัสใหม่กว่า (.NET 4.6+, .NET หลัก ฯลฯ ) โดยทั่วไปควรใช้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;
});
โค้ดที่เก่ากว่าใช้WindowsIdentity.Impersonate
วิธีการดึงWindowsImpersonationContext
วัตถุ วัตถุนี้ใช้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 ขณะนี้ไม่มี. API 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 library ซึ่งรวมการเลียนแบบและการเข้าถึงของผู้ใช้ไปยัง 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
รุ่นที่ใหม่กว่าปลอดภัยกว่ามากและทั้งคู่ยังคงใช้ภายใน