2008-11-03 13 views
20

सी # में, मैं थ्रेड की पहचान कैसे सेट करूं?थ्रेड की पहचान सेट करें

उदाहरण के लिए, अगर मैं थ्रेड MyThread, जो पहले से ही शुरू कर दिया है, मैं MyThread की पहचान को बदल सकते हैं?

या संभव यह नहीं है?

उत्तर

27

आप एक नया प्रिंसिपल बनाकर थ्रेड की पहचान सेट कर सकते हैं। आप किसी भी पहचान का उपयोग कर सकते हैं जो System.Security.Principal.IIdentity से प्राप्त होता है, लेकिन आपको उस श्रेणी की आवश्यकता होती है जो System.Security.Principal.IPrincipal से प्राप्त होती है जो उस प्रकार की पहचान लेती है जिसका आप उपयोग कर रहे हैं।

using System.Security.Principal; 

// ... 
GenericIdentity identity = new GenericIdentity("M.Brown"); 
identity.IsAuthenticated = true; 

// ... 
System.Threading.Thread.CurrentPrincipal = 
    new GenericPrincipal(
     identity, 
     new string[] { "Role1", "Roll2" } 
    ); 

//... 
if (!System.Threading.Thread.CurrentPrincipal.IsInRole("Roll1")) 
{ 
     Console.WriteLine("Permission denied"); 
     return; 
} 

हालांकि यह आप नई पहचान का उपयोग कर सामग्री के लिए खिड़कियों अधिकार नहीं देंगे:
सादगी खातिर नेट ढांचे GenericPrincipal और GenericIdentity वर्ग है जो इस तरह इस्तेमाल किया जा सकता प्रदान करता है। लेकिन यह उपयोगी हो सकता है यदि आप एक वेब साइट विकसित कर रहे हैं और अपना खुद का उपयोगकर्ता प्रबंधन बनाना चाहते हैं।

आप खाते आप वर्तमान में उपयोग कर रहे हैं तो आप प्रतिरूपण उपयोग करने की आवश्यकता के अलावा किसी अन्य Windows उपयोगकर्ता होने का नाटक करना चाहते हैं। ऐसा करने का एक उदाहरण System.Security.Principal.WindowsIdentity.Impersonate() के लिए सहायता में पाया जा सकता है। ऐसी सीमाएं हैं जिनके बारे में आप खाते में खाते का भुगतान कर सकते हैं।

कुछ मामलों में नेट ढांचे आप के लिए प्रतिरूपण करता है। यह कहां होता है इसका एक उदाहरण यह है कि यदि आप एएसपी.Net वेबसाइट विकसित कर रहे हैं और आपके पास वर्चुअल निर्देशिका या साइट के लिए एकीकृत विंडोज प्रमाणीकरण स्विच किया गया है।

+0

में थोड़ा हल्का है यदि आप [जेनेरिक इडेंटिटी कन्स्ट्रक्टर (स्ट्रिंग, स्ट्रिंग) '] (http: // msdn का उपयोग करते हैं। microsoft.com/en-us/library/2wh03ckb(v=vs.110).aspx) आप 'IsAuthenticated = true' बिट को छोड़ सकते हैं। –

+0

मैं .NET 4.5 का उपयोग कर रहा हूं, और मैं इस कथन पहचान को संकलित नहीं कर सकता। यह प्रमाणीकृत = सत्य है; क्योंकि संपत्ति "IsAuthenticated" केवल एक्सेसर प्राप्त कर चुकी है, क्या आप कृपया कोड के लिए एक अद्यतन कर सकते हैं जिसमें .NET 4.5 ढांचे का उपयोग करने का मामला है।धन्यवाद, किसी भी तरह से, आपके कोड की मदद की गई थी, (कुछ संशोधनों के साथ) –

+1

मैंने आपके कोड को जेनेरिक इडेंटिटी पहचान = नई जेनेरिक इडेंटिटी ("उपयोगकर्ता 1", "फॉर्म") बनाने के लिए निम्नलिखित के रूप में .NET 4.5 में संशोधित किया है; थ्रेड। कंटेंट प्रिंसिपल = नया जेनेरिक प्रिंसिपल (पहचान, नई स्ट्रिंग [] {"role1"}); आप सहायक कोड को अपडेट करने के लिए इस कोड का उपयोग कर सकते हैं, धन्यवाद। –

3

हाँ, impersonation सचमुच

using (new Impersonation()) 
{ 
    // your elevated code 
} 

और वर्ग का उपयोग कर के रूप में निम्नानुसार, सेटिंग्स के लिए मैं महल शब्दकोश एडाप्टर का उपयोग करता है, तो यह अजीब लग रहा है।

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")] 
public class Impersonation : IDisposable 
{ 
    private readonly SafeTokenHandle _handle; 
    private readonly WindowsImpersonationContext _context; 

    //const int Logon32LogonNewCredentials = 9; 
    private const int Logon32LogonInteractive = 2; 

    public Impersonation() 
    { 
     var settings = Settings.Instance.Whatever; 
     var domain = settings.Domain; 
     var username = settings.User; 
     var password = settings.Password; 
     var ok = LogonUser(username, domain, password, Logon32LogonInteractive, 0, out _handle); 
     if (!ok) 
     { 
      var errorCode = Marshal.GetLastWin32Error(); 
      throw new ApplicationException(string.Format("Could not impersonate the elevated user. LogonUser returned error code {0}.", errorCode)); 
     } 
     _context = WindowsIdentity.Impersonate(_handle.DangerousGetHandle()); 
    } 

    public void Dispose() 
    { 
     _context.Dispose(); 
     _handle.Dispose(); 
    } 

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken); 

    public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid 
    { 
     private SafeTokenHandle() 
      : base(true) 
     { } 

     [DllImport("kernel32.dll")] 
     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
     [SuppressUnmanagedCodeSecurity] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     private static extern bool CloseHandle(IntPtr handle); 

     protected override bool ReleaseHandle() 
     { 
      return CloseHandle(handle); 
     } 
    } 
} 
+0

आप विस्तार से बता सकते हैं? यदि MyThread पहले से चल रहा था, तो क्या हम इसे वर्तमान प्रिंसिपलर बदल सकते हैं? – Duncan

+0

हाँ, क्या आपने लिंक का पालन किया था? वहाँ उदाहरण हैं। – dove

+0

आश्चर्यजनक रूप से इस लिंक ने मुझे अपनी समस्या को हल करने में मदद की। हालांकि यह थ्रेड पहचान सेट नहीं कर रहा है, यह आपको किसी अन्य उपयोगकर्ता का प्रतिरूपण करते समय कोड चलाने की अनुमति देता है। लिंक में पहले उदाहरण की जांच करके मैंने अपने मुख्य थ्रेड में वर्तमान उपयोगकर्ता पहचान की प्रतिलिपि बनाई: var newId = WindowsIdentity.GetCurrent(); बाद में मैंने इस पहचान को अपने धागे में पास कर दिया और इस खंड के साथ उपयोगकर्ता का प्रतिरूपण किया: (var impersonationContext = newId.Impersonate()) उपयोग के अंदर निष्पादित कोड प्रतिरूपित पहचान के तहत चलाया जाएगा। – Sal

3

यह स्वीकृत उत्तर के लिए एक अद्यतन है [ .NET फ़्रेमवर्क 4.5 और इसके बाद के संस्करण]
.NET 4.5 संपत्ति IsAuthenticated कोई निर्धारित एक्सेसर है, तो आप इसे स्वीकार कर लिया जवाब कर के रूप में सीधे सेट नहीं कर सकता में पर लागू होते हैं।
आप उस संपत्ति को सेट करने के लिए निम्न कोड का उपयोग कर सकते हैं।

GenericIdentity identity = new GenericIdentity("someuser", "Forms"); 
Thread.CurrentPrincipal = new GenericPrincipal(identity, new string[] { "somerole" }); 
संबंधित मुद्दे