.net - System.DirectoryServices का उपयोग करते समय एक अनलोड किए गए ऐपडोमेन तक पहुंचने का प्रयास किया गया




asp.net-mvc visual-studio-2010 (4)

हमने एक सदस्यता प्रदाता लागू किया है जो सक्रिय निर्देशिका को प्रमाणित करता है और यह System.DirectoryServices का उपयोग कर रहा है। Webdev सर्वर के साथ विजुअल स्टूडियो 2010 पर एक एएसपी.NET एमवीसी 3 एप्लिकेशन में इस सदस्यता प्रदाता का उपयोग करते समय हम कभी-कभी (6 बार में से 1) एप्लिकेशन में लॉग इन करते समय अपवाद प्राप्त करते हैं।

System.IO.FileNotFoundException: Could not load file or assembly 'System.Web' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Web' 
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.LoadWithPartialNameInternal(AssemblyName an, Evidence securityEvidence, StackCrawlMark& stackMark)
at System.DirectoryServices.AccountManagement.UnsafeNativeMethods.IADsPathname.Retrieve(Int32 lnFormatType)
at System.DirectoryServices.AccountManagement.ADStoreCtx.LoadDomainInfo()
at System.DirectoryServices.AccountManagement.ADStoreCtx.get_DnsDomainName()
at System.DirectoryServices.AccountManagement.ADStoreCtx.GetGroupsMemberOfAZ(Principal p)
at System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroupsHelper()
at System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroups()

=== Pre-bind state information ===
LOG: DisplayName = System.Web (Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: System.Web | Domain ID: 2
WRN: A partial bind occurs when only part of the assembly display name is provided.
WRN: This might result in the binder loading an incorrect assembly.
WRN: It is recommended to provide a fully specified textual identity for the assembly,
WRN: that consists of the simple name, version, culture, and public key token.
WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
Calling assembly : HibernatingRhinos.Profiler.Appender, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0774796e73ebf640.

कॉलिंग असेंबली HibernatingRhinos.Profiler.Appender था इसलिए log4net कॉन्फ़िगरेशन में प्रोफाइलर को अक्षम करने के बाद हमें वास्तविक अपवाद मिला:

System.AppDomainUnloadedException: Attempted to access an unloaded appdomain. (Except   at System.StubHelpers.StubHelpers.InternalGetCOMHRExceptionObject(Int32 hr, IntPtr pCPCMD, Object pThis)
at System.StubHelpers.StubHelpers.GetCOMHRExceptionObject(Int32 hr, IntPtr pCPCMD, Object pThis)
at System.DirectoryServices.AccountManagement.UnsafeNativeMethods.IADsPathname.Retrieve(Int32 lnFormatType)
at System.DirectoryServices.AccountManagement.ADStoreCtx.LoadDomainInfo()
at System.DirectoryServices.AccountManagement.ADStoreCtx.get_DnsDomainName()
at System.DirectoryServices.AccountManagement.ADStoreCtx.GetGroupsMemberOfAZ(Principal p)
at System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroupsHelper()
at System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroups()

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

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

हमें 2 समान मामले मिले लेकिन किसी को भी वास्तविक समाधान नहीं मिला है:

http://our.umbraco.org/forum/developers/extending-umbraco/19581-Problem-with-custom-membership-and-role-provider

http://forums.asp.net/t/1556949.aspx/1

18-05-2011 अपडेट करें

अपवाद को पुन: पेश करने के लिए कोड की सबसे छोटी मात्रा (एएसपीएनटी एमवीसी में), जहां उपयोगकर्ता नाम आपकी सक्रिय निर्देशिका लॉगइनम है।

using System.DirectoryServices.AccountManagement;
using System.Web.Mvc;

namespace ADBug.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            string userName = "nickvane";
            var principalContext = new PrincipalContext(ContextType.Domain);

            UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(
                principalContext,
                IdentityType.SamAccountName,
                userName);

            if (userPrincipal != null)
            {
                PrincipalSearchResult<Principal> list = userPrincipal.GetAuthorizationGroups();
            }

            return View();
        }
    }
}

हां, अपवाद अभी भी यादृच्छिक रूप से होता है, इसलिए कोई पूरी तरह पुन: उत्पन्न करने योग्य बग नहीं होता है।


ActiveDirectoryMembershipProvider का उपयोग करते समय मुझे एक ही समस्या का सामना करना पड़ा है। मेरे लिए यह तब हो रहा था जब मैंने पहली बार सदस्यता। वैलिडेट यूज़र () कहा और ढांचा प्रदाता बनाने की कोशिश कर रहा था।

मैंने देखा कि मेरे अस्थायी विकास कंप्यूटर में विजुअल स्टूडियो 2010 एसपी 1 स्थापित नहीं था इसलिए मैंने इसे स्थापित किया और इससे मेरे लिए समस्या हल हो गई।


प्रोजेक्ट गुण / वेब टैब / सर्वर अनुभाग पर जाएं और NTML प्रमाणीकरण के लिए चेकबॉक्स में चेक करें।

विंडोज प्रमाणीकरण का उपयोग करने के लिए कैसिनी (वीएस विकास सर्वर) के लिए यह आवश्यक है।


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

सबसे पहले मैं GetRolesForUser विधि को ओवरराइड करता हूं और कैशिंग को कार्यान्वित करता हूं।

    public override string[] GetRolesForUser(string username)
    {
        // List of Windows groups for the given user.
        string[] roles;

        // Create a key for the requested user.
        string cacheKey = username + ":" + ApplicationName;

        // Get the cache for the current HTTP request.
        Cache cache = HttpContext.Current.Cache;
        // Attempt to fetch the list of roles from the cache.
        roles = cache[cacheKey] as string[];
        // If the list is not in the cache we will need to request it.
        if (null == roles)
        {
            // Allow the base implementation to load the list of roles.
            roles = GetRolesFromActiveDirectory(username);
            // Add the resulting list to the cache.
            cache.Insert(cacheKey, roles, null, Cache.NoAbsoluteExpiration,
                Cache.NoSlidingExpiration);
        }

        // Return the resulting list of roles.
        return roles;
    }

GetRolesFromActiveDirectory इस तरह दिखता है।

    public String[] GetRolesFromActiveDirectory(String username)
    {            
        // If SQL Caching is enabled, try to pull a cached value.);));
        if (_EnableSqlCache)
        {
            String CachedValue;
            CachedValue = GetCacheItem('U', username);
            if (CachedValue != "*NotCached")
            {
                return CachedValue.Split(',');
            }
        }

        ArrayList results = new ArrayList();
        using (PrincipalContext context = new PrincipalContext(ContextType.Domain, null, _DomainDN))
        {
            try
            {                    
                UserPrincipal p = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);

                var tries = 0;
                var groups = GetAuthorizationGroups(p, tries);

                foreach (GroupPrincipal group in groups)
                {
                    if (!_GroupsToIgnore.Contains(group.SamAccountName))
                    {
                        if (_IsAdditiveGroupMode)
                        {
                            if (_GroupsToUse.Contains(group.SamAccountName))
                            {
                                results.Add(group.SamAccountName);
                            }
                        }
                        else
                        {
                            results.Add(group.SamAccountName);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new ProviderException("Unable to query Active Directory.", ex);
            }
        }
        // If SQL Caching is enabled, send value to cache
        if (_EnableSqlCache)
        {
            SetCacheItem('U', username, ArrayListToCSString(results));
        }

        return results.ToArray(typeof(String)) as String[];
    }

अंतिम विधि GetAuthorizationGroups है और ऐसा लगता है।

    private PrincipalSearchResult<Principal> GetAuthorizationGroups(UserPrincipal userPrincipal, int tries)
    {
        try
        {
            return userPrincipal.GetAuthorizationGroups();
        }
        catch(FileNotFoundException ex)
        {
            if (tries > 5) throw;

            tries++;
            Thread.Sleep(1000);

            return GetAuthorizationGroups(userPrincipal, tries);
        }
        catch (AppDomainUnloadedException ex)
        {
            if (tries > 5) throw;

            tries++;
            Thread.Sleep(1000);

            return GetAuthorizationGroups(userPrincipal, tries);
        }
    }

मुझे पता चला कि भूमिकाओं को कैशिंग करना इसे बहुत तेज़ बनाता है। उम्मीद है कि यह किसी की मदद करता है। चीयर्स।


यहां मेरे लिए क्या काम करता है (.Net 4):

इसके अलावा:

principalContext = new PrincipalContext(ContextType.Domain)

डोमेन स्ट्रिंग के साथ मुख्य संदर्भ भी बनाएं:

उदाहरण के लिए

principalContext = new PrincipalContext(ContextType.Domain,"MYDOMAIN")

इसे 4.5 में तय किया जाना चाहिए। टिप्पणी देखें, अभी तक तय नहीं किया गया है, लेकिन दूसरा तर्क जोड़ना अभी भी कामकाज के रूप में काम करता है।







visual-studio-2010