c# - एमवीसी से सक्रिय निर्देशिका क्वेरी में परिणाम: एक अनलोड किए गए एपडोमेन तक पहुंचने का प्रयास किया गया।(HRESULT से अपवाद: 0x80131014)




asp.net-mvc model-view-controller (4)

मुझे एक एमवीसी वेब एप्लिकेशन में .Net 4 पर .NET 4 का उपयोग करने का कोई समस्या है, जहां मैं सक्रिय निर्देशिका से पूछता हूं, मुझे अक्सर एक त्रुटि मिलती है: एक अनलोड किए गए ऐपडोमेन तक पहुंचने का प्रयास किया जाता है। (HRESULT से अपवाद: 0x80131014)।

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

मैंने इसे काम करने के लिए फ़ंक्शन में कुछ संशोधन किए हैं, लेकिन वे सभी असफल होने लगते हैं। मैं सोच रहा हूं कि क्या मैं कुछ गलत कर रहा हूं, या अगर ऐसा करने का बेहतर तरीका है।

मेरा वर्तमान फ़ंक्शन यहां है, जो लॉगिन आईडी स्वीकार करेगा, और प्रिंसिपल कॉन्टेक्स्ट। LoginId या तो उपयोगकर्ता डिस्प्लेनाम यानी "जॉन स्मिथ" या DOMAINNAME \ josmi हो सकता है । डिफ़ॉल्ट उनके पहले नाम के पहले 2 अक्षरों का उपयोग करना है, और उसके बाद उनके उपनाम के पहले 3 अक्षर। अगर ऐसा नहीं है तो वहां एक जांच है। अगर यह हिस्सा ठीक है।

public List<ADGroup> GetMemberGroups(string loginId, PrincipalContext principalContext, int tries = 0)
{
    var result = new List<ADGroup>();

    try
    {
        var samAccountName = "";
        if (loginId.Contains(" "))
        {
            var fName = loginId.Split(Char.Parse(" "))[0].ToLower();
            var sName = loginId.Split(Char.Parse(" "))[1].ToLower();

            if (sName.Trim().Length == 2)
                samAccountName = string.Format("{0}{1}", fName.StartsWith(".") ? fName.Substring(0, 4) : fName.Substring(0, 3), sName.Substring(0, 2));
            else
                samAccountName = string.Format("{0}{1}", fName.StartsWith(".") ? fName.Substring(0, 3) : fName.Substring(0, 2), sName.Substring(0, 3));
        }
        else
            samAccountName = loginId.Substring(loginId.IndexOf(@"\") + 1);

        var authPrincipal = UserPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, samAccountName);

        if (authPrincipal == null)
            throw new Exception(string.Format("authPrincipal is null for loginId - {0}", loginId));

        var firstLevelGroups = authPrincipal.GetGroups();

        AddGroups(firstLevelGroups, ref result);
    }
    catch
    {
        if (tries > 5)
            throw;

        tries += 1;

        System.Threading.Thread.Sleep(1000);
        GetMemberGroups(loginId, principalContext, tries);
    }

    return result;
}

    private void AddGroups(PrincipalSearchResult<Principal> principal, ref List<ADGroup> returnList)
    {
        foreach (var item in principal)
        {
            if (item.GetGroups().Count() > 0)
                AddGroups(item.GetGroups(), ref returnList);

            returnList.Add(new ADGroup(item.SamAccountName, item.Sid.Value));
        }
    }

इस समारोह को इस तरह कहा जाता है:

MembershipGroups = ad.GetMemberGroups(user.SamAccountName, new PrincipalContext(ContextType.Domain));

मुझे जो त्रुटि मिलती है वह है:

System.AppDomainUnloadedException: एक अनलोड किए गए ऐपडोमेन तक पहुंचने का प्रयास किया गया। (HRESULT: 0x80131014 से अपवाद) System.StubHelpers.StubHelpers.InternalGetCOMHRExceptionObject (Int32 घंटा, IntPtr पीसीपीसीएमडी, ऑब्जेक्ट pThis) System.StubHelpers.StubHelpers.GetCOMHRExceptionObject (Int32 घंटा, IntPtr पीसीपीसीएमडी, ऑब्जेक्ट pThis) सिस्टम पर। डायरेक्टरी सर्विसेज। खाता प्रबंधन। UnsafeNativeMethods.IADsPathname.Retrieve System.DirectoryServices.AccountManagement.ADStoreCtx.LoadDomainInfo पर (Int32 lnFormatType) () System.DirectoryServices.AccountManagement.ADStoreCtx.get_UserSuppliedServerName पर () System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet.BuildPathFromDN पर (स्ट्रिंग dn) सिस्टम पर। 1.MoveNext() at System.DirectoryServices.AccountManagement.FindResultEnumerator System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet.MoveNext () पर System.DirectoryServices.AccountManagement.FindResultEnumerator 1.MoveNext() at System.DirectoryServices.AccountManagement.FindResultEnumerator 1. सिस्टम। चयन। INumerator। MoveNext ()


System.DirectoryServices.AccountManagement में आंतरिक क्लाइंट "असुरक्षित मोड" को मूल कोड में कार्यान्वित किया गया है, इसलिए UserSuppliedServerName एक स्तर ऊपर है जिसे मैं सीएलआर वीएम को देखे बिना जा सकता हूं, (स्पष्ट रूप से मुझे यह सुनिश्चित नहीं है कि यह कैसे करें) ऐसा लगता है कि एक नोड अपने प्राथमिक समूह को वापस करने में असफल रहा है, इसलिए शायद अन्य कार्यान्वयन पर विचार करें, थोड़ी सी गुगलिंग के बाद इन्हें मदद मिल सकती है

  • सक्रिय निर्देशिका और नेस्टेड समूह यह वादा कर सकते हैं कोड नमूना heres ..

        public IList<string> FindUserGroupsLdap(string username)
    { 
        // setup credentials and connection  
        var credentials = new NetworkCredential("username", "password", "domain");  
        var ldapidentifier = new LdapDirectoryIdentifier("server", 389, true, false); 
        var ldapConn = new LdapConnection(ldapidentifier, credentials); 
        // retrieving the rootDomainNamingContext, this will make sure we query the absolute root   
        var getRootRequest = new SearchRequest(string.Empty, "objectClass=*", SearchScope.Base, "rootDomainNamingContext");  
        var rootResponse = (SearchResponse)ldapConn.SendRequest(getRootRequest);   
        var rootContext = rootResponse.Entries[0].Attributes["rootDomainNamingContext"][0].ToString();  
        // retrieve the user 
        string ldapFilter = string.Format("(&(objectCategory=person)(sAMAccountName={0}))", username); 
        var getUserRequest = new SearchRequest(rootContext, ldapFilter, SearchScope.Subtree, null);  
        var userResponse = (SearchResponse)ldapConn.SendRequest(getUserRequest);     
        // send a new request to retrieve the tokenGroups attribute, we can not do this with our previous request since 
        // tokenGroups needs SearchScope.Base (dont know why...)  
        var tokenRequest = new SearchRequest(userResponse.Entries[0].DistinguishedName, "(&(objectCategory=person))", SearchScope.Base, "tokenGroups");  
        var tokenResponse = (SearchResponse)ldapConn.SendRequest(tokenRequest);  
        var tokengroups = tokenResponse.Entries[0].Attributes["tokenGroups"].GetValues(typeof(byte[])); 
        // build query string this query will then look like (|(objectSid=sid)(objectSid=sid2)(objectSid=sid3))  
        // we need to convert the given bytes to a hexadecimal representation because thats the way they   
        // sit in ActiveDirectory  
        var sb = new StringBuilder();  
        sb.Append("(|");   
        for (int i = 0; i < tokengroups.Length; i++)  
        {  
            var arr = (byte[])tokengroups[i];    
            sb.AppendFormat("(objectSid={0})", BuildHexString(arr));   
        }   
        sb.Append(")");    
        // send the request with our build query. This will retrieve all groups with the given objectSid
        var groupsRequest = new SearchRequest(rootContext, sb.ToString(), SearchScope.Subtree, "sAMAccountName"); 
        var groupsResponse = (SearchResponse)ldapConn.SendRequest(groupsRequest); 
        // loop trough and get the sAMAccountName (normal, readable name)   
        var userMemberOfGroups = new List<string>();    
        foreach (SearchResultEntry entry in groupsResponse.Entries)    
        userMemberOfGroups.Add(entry.Attributes["sAMAccountName"][0].ToString());  
        return userMemberOfGroups;
    } 
    
    private string BuildHexString(byte[] bytes)
    {  
        var sb = new StringBuilder(); 
        for (int i = 0; i < bytes.Length; i++) 
        sb.AppendFormat("\\{0}", bytes[i].ToString("X2")); 
        return sb.ToString();
    }
    

ये जानकारी उद्देश्यों के लिए अधिक हैं


आप समस्या को कम करने के लिए कुछ लॉगिंग डाल सकते हैं। वह Thread.Sleep कुछ ऐसा नहीं दिखता जो किसी वेब एप्लिकेशन में चाहता है :)

यदि आपको अपवाद मिल रहे हैं तो आप उन्हें अलग-अलग संभालेंगे।

मुझे लगता है कि आपके ऐपडोमेन का पुनर्नवीनीकरण किया जा रहा है जबकि एडी अपना वूडू कर रहा है। Application_End लॉगिंग जोड़ना कुछ सुराग भी प्रदान कर सकता है।


मुझे नहीं पता कि PrincipalContext कैसे यहां पारित किया जा रहा है, लेकिन जब मैंने यह त्रुटि प्राप्त की, तो मैंने अपने कोड और शोध में एक बात देखी, मेरे पास था:

PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain);
UserPrincipal oUserPrincipal = UserPrincipal.FindByIdentity(oPrincipalContext , strUserName);

जहां strUserName कुछ उपयोगकर्ता था, यानी DOMAIN\johndoe

मैं उस कोड को कॉल कर रहा था (जो एक अलग समारोह में था) और उपयोगकर्ता UserPrincipal ऑब्जेक्ट को वापस up और इसे पास करने के लिए:

using (PrincipalSearchResult<Principal> result = up.GetGroups())
{
    // do something with result, here
}

result शून्य नहीं होगा, लेकिन जब मैंने उस स्थिति की जांच की, तो मैंने result.Count() > 0 , और जब यह असफल हो जाता है (कभी-कभी - हालांकि मैं इसे फिर से बना सकता हूं जब यह क्लिक करके होता है मेरे ऐप में एक विशेष टैब जिसे इस कोड कहा जाता है - भले ही एक ही कोड को मेरे ऐप के ऑनलोड कहा जाता था और इसमें कोई समस्या नहीं थी)। result Message संपत्ति Attempted to access an unloaded appdomain. (Exception from HRESULT: 0x80131014) का Attempted to access an unloaded appdomain. (Exception from HRESULT: 0x80131014) गया था Attempted to access an unloaded appdomain. (Exception from HRESULT: 0x80131014) Attempted to access an unloaded appdomain. (Exception from HRESULT: 0x80131014)

मुझे इस तरह की एक पोस्ट में मिला कि मुझे बस इतना करना था कि मेरे PrincipalContext में डोमेन निर्दिष्ट किया गया था। चूंकि मैं अपने कोड को हार्ड कोड नहीं कर सका, क्योंकि हम अपने कोड को देव, टेस्ट और प्रोडक्शन वातावरण के बीच ले जाते हैं, जहां इनमें से प्रत्येक के लिए अलग-अलग डोमेन हैं, मैं इसे Environment.UserDomainName रूप में निर्दिष्ट करने में सक्षम था। यूज़र डोमेन नाम:

PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain, Environment.UserDomainName);

यह मेरे लिए त्रुटि से छुटकारा पा लिया।


यह समस्या यह निर्धारित करने के समान है कि उपयोगकर्ता .NET 4.0 एप्लिकेशन के लिए एडी समूह में है या नहीं

यह एडीएसआई में एक बग प्रतीत होता है जिसे हॉटफिक्स के साथ हल किया गया था। विंडोज 7 एसपी 1 और विंडोज सर्वर 2008 आर 2 एसपी 1 में फिक्स शामिल नहीं है, इसलिए इसे आपकी विकास मशीनों और सर्वर वातावरण पर मैन्युअल रूप से तैनात करने की आवश्यकता होगी।

http://support.microsoft.com/kb/2683913





active-directory