तो जैसे कोड का उपयोग कर किसी अन्य उपयोगकर्ता,.NET प्रतिरूपण लॉगऑन थ्रेड-सुरक्षित है?
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool
LogonUser(string lpszUsername, string lpszDomain,
string lpszPassword, int dwLogonType,
int dwLogonProvider, ref IntPtr phToken);
var handle = IntPtr.Zero;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int SecurityImpersonation = 2;
LogonUser(username, domain,
password, LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT, ref handle))
दो विभिन्न समवर्ती धागे पर प्रतिरूपित करने के लिए, वे एक दूसरे के साथ हस्तक्षेप करेगा निम्नलिखित? यानी, क्या वर्तमान में लॉग-ऑन उपयोगकर्ता थ्रेड से जुड़ा हुआ है, या मेजबान प्रक्रिया के साथ?
मैं एक विंडोज़ इम्पर्सनेशन कॉन्टेक्स्ट ऑब्जेक्ट बनाने के लिए लॉगऑन हैंडल का उपयोग कर रहा हूं, जिसे एक निजी राज्य क्षेत्र के रूप में "इंपर्सोनेटर" (नीचे कोड) नाम दिया गया है। इसलिए, चूंकि यह WindowsImpersonationContext ऑब्जेक्ट इस प्रकार के उदाहरण में एक स्थानीय निजी फ़ील्ड है, और प्रत्येक बार जब मैं क्रेडेंशियल के कुछ सेट का प्रतिरूपण करना चाहता हूं, तो इस प्रकार का एक नया उदाहरण बनाया गया है, मैं मान सकता हूं कि यह WindowsImpersonationContext का उपयोग किया जा रहा है
किसी भी सार्वजनिक स्थैतिक (विजुअल बेसिक में साझा): एक जैसे
using (Impersonator.Impersonate(userId, domain, password)) { // Code I want to execute using supplied credentials }
क्या मुझे चिंतित है MSDN पेज WindowsImpersonationContext कि कहते हैं पर बयान है ब्लॉक के भीतर कोड के निष्पादन के दौरान सभी एसीएल सत्यापन प्रदर्शन इस प्रकार के सदस्य धागे सुरक्षित हैं। किसी भी इंस्टेंस सदस्यों को थ्रेड सुरक्षित होने की गारंटी नहीं है।
Impersonator
वर्ग:
public class Impersonator: IDisposable
{
#region Declarations
private readonly string username;
private readonly string password;
private readonly string domain;
// This will hold the security context
// for reverting back to the client after
// impersonation operations are complete
private WindowsImpersonationContext impersonationContext;
#endregion Declarations
#region Constructors
public Impersonator(string UserName,
string Domain, string Password)
{
username = UserName;
domain = Domain;
password = Password;
}
#endregion Constructors
#region Public Methods
public static Impersonator Impersonate(
string userName, string domain, string password)
{
var imp = new Impersonator(userName, domain, password);
imp.Impersonate();
return imp;
}
public void Impersonate()
{
impersonationContext = Logon().Impersonate();
}
public void Undo() {
impersonationContext.Undo();
}
#endregion Public Methods
#region Private Methods
private WindowsIdentity Logon()
{
var handle = IntPtr.Zero;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int SecurityImpersonation = 2;
// Attempt to authenticate domain user account
try
{
if (!LogonUser(username, domain,
password, LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT, ref handle))
throw new LogonException(
"User logon failed. Error Number: " +
Marshal.GetLastWin32Error());
// ----------------------------------
var dupHandle = IntPtr.Zero;
if (!DuplicateToken(handle,
SecurityImpersonation,
ref dupHandle))
throw new LogonException(
"Logon failed attemting to duplicate handle");
// Logon Succeeded ! return new WindowsIdentity instance
return (new WindowsIdentity(handle));
}
// Close the open handle to the authenticated account
finally { CloseHandle(handle); }
}
#region external Win32 API functions
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool
LogonUser(string lpszUsername, string lpszDomain,
string lpszPassword, int dwLogonType,
int dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
// --------------------------------------------
[DllImport("advapi32.dll", CharSet = CharSet.Auto,
SetLastError = true)]
public static extern bool DuplicateToken(
IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL,
ref IntPtr DuplicateTokenHandle);
// --------------------------------------------
#endregion external Win32 API functions
#endregion Private Methods
#region IDisposable
private bool disposed;
public void Dispose() { Dispose(true); }
public void Dispose(bool isDisposing)
{
if (disposed)
return;
if (isDisposing)
Undo();
// -----------------
disposed = true;
GC.SuppressFinalize(this);
}
~Impersonator() {
Dispose(false);
}
#endregion IDisposable
}
ठीक है, मैं एक विंडोज़ इम्पर्सनेशन कॉन्टेक्स्ट ऑब्जेक्ट बनाने के लिए उस हैंडल का उपयोग करता हूं, जो थ्रेड-सुरक्षित है, (यह प्रति उपयोग किए गए परिभाषित प्रकार का एक उदाहरण है)। "जुड़े" से, मेरा मतलब था कि लॉगऑन हैंडल कहां संग्रहीत है? जैसा कि मैं इसे समझता हूं, यह WindowsImpersonationContext ऑब्जेक्ट है जो सुरक्षा संदर्भ के संदर्भ में "रखता है", और यदि यह थ्रेड में साझा नहीं किया गया है तो मुझे ठीक होना चाहिए ... सही? –
मुझे एमएसडीएन पेज http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx पर बयान क्या है, जो कहता है: "कोई भी सार्वजनिक स्थैतिक (विजुअल बेसिक में साझा) इस प्रकार के सदस्य थ्रेड सुरक्षित हैं। किसी भी इंस्टेंस सदस्यों को थ्रेड सुरक्षित होने की गारंटी नहीं है। " –
@ चार्ल्स ब्रेटाना: WindowsImpersonationContext इंस्टेंस के इंस्टेंस सदस्य थ्रेड-सुरक्षित नहीं हैं। आप गारंटीकृत सुरक्षा के साथ कई धागे से एक ही उदाहरण में कॉल नहीं कर सकते हैं। यह ऑब्जेक्ट .NET में अधिकांश लोगों की तरह है, उदाहरण के सदस्य थ्रेड-सुरक्षित नहीं हैं, स्थिर सदस्य हैं। जहां लॉग इन हैंडल संग्रहीत किया जाता है, हैंडल इंटिप्ट में है, जो लॉगिन टोकन के लिए जानकारी को इंगित करता है। – casperOne