2012-09-26 17 views
28

.NET 4.5 के तहत हमारे .NET 4.0 एप्लिकेशन का परीक्षण करने में, हमें के लिए FindByIdentity विधि के साथ समस्या आई है। निम्नलिखित कोड काम करता है जब एक .NET 4.0 क्रम में चलाने के लिए, लेकिन विफल रहता है .NET 4.5 के तहत:उपयोगकर्ता प्रिंसिपल में .NET 4.5 बग। FIindByIdentity (System.DirectoryServices.AccountManagement)

[Test] 
public void TestIsAccountLockedOut() 
{ 
    const string activeDirectoryServer = "MyActiveDirectoryServer"; 
    const string activeDirectoryLogin = "[email protected]"; 
    const string activeDirectoryPassword = "MyADAccountPassword"; 
    const string userAccountToTest = "[email protected]"; 
    const string userPasswordToTest = "WRONGPASSWORD"; 

    var principalContext = new PrincipalContext(ContextType.Domain, activeDirectoryServer, activeDirectoryLogin, activeDirectoryPassword); 

    var isAccountLockedOut = false; 
    var isAuthenticated = principalContext.ValidateCredentials(userAccountToTest, userPasswordToTest, principalContext.Options); 
    if (!isAuthenticated) 
    { 
     // System.DirectoryServices.AccountManagement.PrincipalOperationException : Information about the domain could not be retrieved (1355). 
     using (var user = UserPrincipal.FindByIdentity(principalContext, IdentityType.UserPrincipalName, userAccountToTest)) 
     { 
      isAccountLockedOut = (user != null) && user.IsAccountLockedOut(); 
     } 
    } 
    Assert.False(isAuthenticated); 
    Assert.False(isAccountLockedOut); 
} 

यहाँ अपवाद स्टैक ट्रेस है:

System.DirectoryServices.AccountManagement.PrincipalOperationException : Information about the domain could not be retrieved (1355). 
at System.DirectoryServices.AccountManagement.Utils.GetDcName(String computerName, String domainName, String siteName, Int32 flags) at System.DirectoryServices.AccountManagement.ADStoreCtx.LoadDomainInfo() at 
System.DirectoryServices.AccountManagement.ADStoreCtx.get_DnsDomainName() at System.DirectoryServices.AccountManagement.ADStoreCtx.GetAsPrincipal(Object storeObject, Object discriminant) at 
System.DirectoryServices.AccountManagement.ADStoreCtx.FindPrincipalByIdentRefHelper(Type principalType, String urnScheme, String urnValue, DateTime referenceDate, Boolean useSidHistory) at 
System.DirectoryServices.AccountManagement.ADStoreCtx.FindPrincipalByIdentRef(Type principalType, String urnScheme, String urnValue, DateTime referenceDate) at 
System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate) at 
System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, IdentityType identityType, String identityValue) at 
System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue) 

किसी और को देखा है और इस समस्या का समाधान है? यदि नहीं, तो क्या सक्रिय निर्देशिका खाते के लिए IsAccountLockedOut स्थिति जांचने का हमारे लिए एक बेहतर तरीका है?

संदर्भ के लिए, हमारी सभी परीक्षण मशीनें एक ही सबनेट के भीतर हैं। विभिन्न डोमेन कार्यात्मक मोड (नीचे देखें) में, Windows Server 2003, 2008 और 2012 चला रहे अलग ActiveDirectory सर्वर हैं। यह कोड .NET 4.0 चलाने वाली मशीनों से काम करता है, लेकिन .NET 4.5 चलाने वाली मशीनों में विफल रहता है।

तीन नेट मशीनों हम से कोड दौड़ा कर रहे हैं:
- विंडोज 7 .NET 4.0
चल रहा है - Windows Vista चल .NET 4.5
- विंडोज सर्वर 2012 चल रहा है .NET 4.5

सक्रिय निर्देशिका सर्वर हम कोशिश की है इस प्रकार हैं:
- Windows 2003 ई डोमेन कार्यात्मक मोड Windows 2000 देशी
करने के लिए सेट के साथ - साथ ई डोमेन कार्यात्मक मोड रों विंडोज 2008 - ई डोमेन कार्यात्मक मोड विंडोज सर्वर 2003
करने के लिए सेट के साथ Windows 2003 विंडोज 2008 ई डोमेन कार्यात्मक मोड विंडोज सर्वर 2003
करने के लिए सेट के साथ - - विंडोज 2012 ई डोमेन कार्यात्मक मोड Windows 2012

करने के लिए सेट के साथ - ई डोमेन कार्यात्मक मोड Windows सर्वर के लिए सेट 2008
साथ Windows 2008 Windows 2000 देशी
को एट

उन सभी सक्रिय निर्देशिका सर्वरों को एक साधारण, एकल वन के रूप में कॉन्फ़िगर किया गया है, और क्लाइंट मशीन डोमेन का हिस्सा नहीं हैं। इन व्यवहारों का परीक्षण करने के बजाय इनका उपयोग किसी अन्य कार्य के लिए नहीं किया जाता है, और सक्रिय निर्देशिका के अलावा कुछ भी नहीं चल रहा है।


संपादित करें - 9 अक्टू 2012

हर किसी के लिए धन्यवाद कि उत्तर दिया। नीचे एक सी # कमांड-लाइन क्लाइंट है जो समस्या का प्रदर्शन करता है, और एक अल्पकालिक कार्यवाही जिसे हमने पहचाना है जिसके लिए हमें सक्रिय निर्देशिका और DNS कॉन्फ़िगरेशन के बारे में कुछ भी बदलने की आवश्यकता नहीं है। ऐसा प्रतीत होता है कि अपवाद केवल प्रिंसिपल कॉन्टेक्स्ट के उदाहरण के साथ फेंक दिया जाता है। हमने .NET 4.0 मशीन (विंडोज 7) और एक .NET 4.5 मशीन (विंडोज विस्टा) के लिए आउटपुट शामिल किए।

using System; 
using System.DirectoryServices.AccountManagement; 

namespace ADBug 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      const string activeDirectoryServer = "MyActiveDirectoryServer"; 
      const string activeDirectoryLogin = "MyADAccount"; 
      const string activeDirectoryPassword = "MyADAccountPassword"; 
      const string validUserAccount = "[email protected]"; 
      const string unknownUserAccount = "[email protected]"; 

      var principalContext = new PrincipalContext(ContextType.Domain, activeDirectoryServer, activeDirectoryLogin, activeDirectoryPassword); 

      // .NET 4.0 - First attempt with a valid account finds the user 
      // .NET 4.5 - First attempt with a valid account fails with a PrincipalOperationException 
      TestFindByIdentity(principalContext, validUserAccount, "Valid Account - First Attempt"); 
      // Second attempt with a valid account finds the user 
      TestFindByIdentity(principalContext, validUserAccount, "Valid Account - Second Attempt"); 
      // First attempt with an unknown account does not find the user 
      TestFindByIdentity(principalContext, unknownUserAccount, "Unknown Account - First Attempt"); 
      // Second attempt with an unknown account does not find the user (testing false positive) 
      TestFindByIdentity(principalContext, unknownUserAccount, "Unknown Account - Second Attempt"); 
      // Subsequent attempt with a valid account still finds the user 
      TestFindByIdentity(principalContext, validUserAccount, "Valid Account - Third Attempt"); 
     } 

     private static void TestFindByIdentity(PrincipalContext principalContext, string userAccountToTest, string message) 
     { 
      var exceptionThrown = false; 
      var userFound = false; 
      try 
      { 
       using (var user = UserPrincipal.FindByIdentity(principalContext, IdentityType.UserPrincipalName, userAccountToTest)) 
       { 
        userFound = (user != null); 
       } 
      } 
      catch (PrincipalOperationException) 
      { 
       exceptionThrown = true; 
      } 
      Console.Out.WriteLine(message + " - Exception Thrown = {0}", exceptionThrown); 
      Console.Out.WriteLine(message + " - User Found = {1}", userAccountToTest, userFound); 
     } 
    } 
} 

.NET 4.0 आउटपुट

Valid Account - First Attempt - Exception Thrown = False 
Valid Account - First Attempt - User Found = True 
Valid Account - Second Attempt - Exception Thrown = False 
Valid Account - Second Attempt - User Found = True 
Unknown Account - First Attempt - Exception Thrown = False 
Unknown Account - First Attempt - User Found = False 
Unknown Account - Second Attempt - Exception Thrown = False 
Unknown Account - Second Attempt - User Found = False 
Valid Account - Third Attempt - Exception Thrown = False 
Valid Account - Third Attempt - User Found = True 

.NET 4.5 आउटपुट

Valid Account - First Attempt - Exception Thrown = True 
Valid Account - First Attempt - User Found = False 
Valid Account - Second Attempt - Exception Thrown = False 
Valid Account - Second Attempt - User Found = True 
Unknown Account - First Attempt - Exception Thrown = False 
Unknown Account - First Attempt - User Found = False 
Unknown Account - Second Attempt - Exception Thrown = False 
Unknown Account - Second Attempt - User Found = False 
Valid Account - Third Attempt - Exception Thrown = False 
Valid Account - Third Attempt - User Found = True 
+1

यह सुनिश्चित नहीं है कि आपने अभी तक इसे गुगल किया है, लेकिन मुझे विभिन्न दृश्यों के लिए फिक्स के लिए कई टिप्पणियों के साथ एक पोस्ट मिली ओएस जो इसका कारण बन सकता है: http://elegantcode.com/2009/03/21/one-scenario-where-the-systemdirectoryservices-accountmanagement-api-falls-down/ मैंने इसे कभी नहीं देखा है, लेकिन ब्याज में सहायक होने के नाते, मैंने सोचा कि मैं इसे साझा करूंगा क्योंकि यह मेरे लिए उपयोगी लगता है। उदाहरण के लिए – David

+0

आप ( ContextType.Domain, "fabrikam.com", उदाहरण के PrincipalContext ctx = नए PrincipalContext के लिए डीसी और सीएन में गुजर की कोशिश की है "सीएन = उपयोगकर्ता, डीसी = Fabrikam, डीसी = कॉम", "व्यवस्थापक" , "सुरक्षित रूप से संग्रहीत पासवर्ड"); – MethodMan

+0

डीजे, हमने अभी सीएन और डीसी स्ट्रिंग में गुजरने की कोशिश की है, और यह अभी भी .NET 4.0 के तहत काम करता है और .NET 4.5 के अंतर्गत विफल रहता है। –

उत्तर

12

हम ठीक उसी मुद्दा (क्रॉस डोमेन प्रश्नों 4.5 को अद्यतन करने में नाकाम रहने पर) का सामना कर रहे हैं - मैं पर विचार करेंगे यह एक बग है क्योंकि यह मौजूदा (4.0) कोड तोड़ता है।

हालांकि, यह काम कर रही है के हित में - की (अब) एक ग्राहकों में नाकाम रहने पर एक नज़र डालने, मैंने देखा है SRV रिकॉर्ड उस प्रपत्र के नाकाम रहने के थे, के लिए DNS अनुरोधों का एक समूह वहाँ थे कि:

_ldap._tcp.MYSERVER1.mydomain.com,INet,Srv 
_ldap._tcp.dc._msdcs.mydomain.com,INet,Srv 

डोमेन पर डीसी में से किसी एक को my mydomain.com यातायात के लिए एक आगे क्षेत्र रखने के लिए हमारे DNS सर्वर (असफल ग्राहकों द्वारा उपयोग किया जाने वाला DNS) को संशोधित करने से समस्या हल हो गई।

nslookup का उपयोग करना, पहले से व्यवहार (जब यह असफल रहा था) के लिए अब (कार्य) है कि पहले उन प्रश्नों "गैर-मौजूद डोमेन" वापसी होगी अब जबकि वे लौटने "* कोई सेवा स्थान (SRV) रिकॉर्ड था के लिए उपलब्ध है ..."। असफलता का बिंदु एसआरवी रिकॉर्ड लापता होने के बजाय डोमेन की कथित गैर-अस्तित्व प्रतीत होता है। उम्मीद है कि एमएस इस व्यवहार को उलट देता है लेकिन इस बीच यदि आप असफल ग्राहकों के लिए DNS को नियंत्रित कर सकते हैं तो आपके पास कुछ भाग्य एक DNS फॉरवर्ड जोन बनाना हो सकता है।

5

ओपी (और किसी और ने उत्तर देने में मदद की) के लिए हमारे पास एक ही सटीक समस्या है (था)। हमारे विकास पर्यावरण में, वीएस2012 स्थापित किया गया और हमारा ऐप लॉगिन के दौरान रनटाइम पर टूट गया (एडी मुद्दा ऊपर बताए गए अनुसार)। इसलिए मैंने 2010 में अपने सिस्टम को मिटा दिया और जारी रखा, हर बार एक आंसू बहाल करते हुए आईडी ने एक नया ब्लॉग पोस्ट पढ़ा कि 2012 कितना भयानक है।

तो मुझे स्कॉट हंसेलमैन को यह धागा धन्यवाद मिला। मैंने अपने विकास बॉक्स पर एक वीएम स्थापित किया, विंडोज 8 डेवलपर 90 दिन का पूर्वावलोकन, और वीएस2012। हमारे आवेदन को मिला और चल रहा था और तुरंत लॉगिन एडी स्नैग के साथ मारा गया था। बस एक कोशिश पकड़ने में हमारी FindByIdentity लपेटा और इसे पहली पकड़ के बाद फिर कोशिश करने के लिए मजबूर किया - और व्हायोला यह काम करता है !! तो किसी को भी उस छोटी सी चाल का पता लगाने के लिए धन्यवाद !!

तो, यह मामूली फिक्स है, और एक "हैक" जो स्थानीय विकास के लिए काम करता है, और उत्पादन को प्रभावित नहीं करना चाहिए क्योंकि हम जल्द ही उत्पादन पर 4.5 डाल नहीं रहे हैं।

लेकिन नकारात्मक पक्ष यह है कि स्थानीय स्तर पर, अब है में प्रवेश करने सेकंड बनाम 2 की तरह ही मिनट लगते हैं जब हम 2010 :(

के तहत भाग गया मैं वास्तव में नहीं जानता कि और क्या मैं वास्तव में स्थिति के समाधान में मदद करने के लिए प्रयास करने के लिए प्रदान कर सकते हैं , लेकिन यह पता लगाया गया है कि आईडी अभी भी एक बड़ा मुद्दा प्रतीत होता है।

+3

प्रतिक्रिया के लिए धन्यवाद। हमने एक ही व्यवहार की पुष्टि की (पहला प्रयास विफल रहता है, बाद में सफल होता है) और ऊपर एक परीक्षण क्लाइंट पोस्ट किया। माइक्रोसॉफ्ट से प्राप्त आखिरी फीडबैक निम्न था: _ ".NET4.5 में SDS.AM ने क्लाइंट साइड पर डोमेन DNS रिज़ॉल्यूशन की आवश्यकता के लिए एक प्रतिबंध जोड़ा। यह डिज़ाइन किया गया था क्योंकि DNS सर्वोत्तम अभ्यास में सही DNS प्रविष्टि होनी चाहिए। मंच से प्रतिक्रिया, हम भावी रिलीज में प्रतिबंध को हटाने पर विचार कर रहे हैं। "_ –

+0

धन्यवाद! एक बात मैंने यह भी ध्यान में रखी है कि पहली कोशिश विफलता पकड़ने के बाद - एडी को किसी भी कॉल में एक बड़ी देरी भी होती है - 3 मिनट + बात कर रही है। क्या मेरे स्थानीय मेजबान में प्रविष्टियां हैं जो मैं इस तरह के मुद्दे को ठीक करने के लिए जोड़ सकता हूं? फीडबैक के लिए फिर से धन्यवाद! – jkat98

+0

मुझे यकीन नहीं है कि यह संबंधित है, लेकिन सर्वर के लिए आईपी पते (उदा। 192.168.14.3) के बजाय होस्टनाम (उदा। Myserver) का उपयोग करने के साथ हमारे पास हमेशा महत्वपूर्ण प्रदर्शन समस्याएं हैं। हमने इस समस्या के लिए प्रयास-पकड़ कार्यवाही का कोई प्रदर्शन परीक्षण नहीं किया है, लेकिन मैं एक परीक्षण केस फेंक दूंगा और देख सकता हूं कि हम किस प्रकार की संख्या के साथ आते हैं। –

0

4.0 से 4.5 से नेट फ्रेमवर्क को अपग्रेड करने के बाद भी एक ही समस्या थी। मैंने 4.5.1 पर ugpraded फ्रेमवर्क किया है और यह काम करता है।