c#通过模拟访问DirectoryEntry只会在第一次抛出灾难性异常



我正在使用以下c#代码冒充用户:

    SafeTokenHandle logon_token = null;
    SafeTokenHandle duplicate_token = null;
    const int LOGON32_PROVIDER_DEFAULT = 0;
    const int LOGON32_LOGON_INTERACTIVE = 2;
    const int SecurityImpersonation = 2;

    if (!LogonUser(m_Username, m_Domain, m_Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,out logon_token))
    {
        throw new Win32Exception(Marshal.GetLastWin32Error());
    }
    using (logon_token)
    {
        if (!DuplicateToken(logon_token, SecurityImpersonation, out duplicate_token))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        using (duplicate_token)
        {
            using (WindowsIdentity new_id = new WindowsIdentity(logon_token.DangerousGetHandle()))
            {
                using (WindowsImpersonationContext impersonatedUser = new_id.Impersonate())
                {
                    return invocation_delegate(param);
                }
            }
        }
    }

其中invocation_delegate将调用将使用DirectoryEntry(使用Secure AuthenticationType)访问Active Directory对象的方法。

我的问题是,当我第一次调用DirectoryEntry功能时,它抛出了以下异常:

Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
at System.Security.Policy.PEFileEvidenceFactory.GetLocationEvidence(SafePEFileHandle peFile, SecurityZone& zone, StringHandleOnStack retUrl)
at System.Security.Policy.PEFileEvidenceFactory.GenerateLocationEvidence()
at System.Security.Policy.PEFileEvidenceFactory.GenerateEvidence(Type evidenceType)
at System.Security.Policy.AssemblyEvidenceFactory.GenerateEvidence(Type evidenceType)
at System.Security.Policy.Evidence.GenerateHostEvidence(Type type, Boolean     hostCanGenerate)
at System.Security.Policy.Evidence.GetHostEvidenceNoLock(Type type)
at System.Security.Policy.Evidence.GetHostEvidence(Type type, Boolean markDelayEvaluatedEvidenceUsed)
at System.Security.Policy.AppDomainEvidenceFactory.GenerateEvidence(Type evidenceType)
at System.Security.Policy.Evidence.GenerateHostEvidence(Type type, Boolean hostCanGenerate)
at System.Security.Policy.Evidence.GetHostEvidenceNoLock(Type type)
at System.Security.Policy.Evidence.RawEvidenceEnumerator.MoveNext()
at System.Security.Policy.Evidence.EvidenceEnumerator.MoveNext()
at System.Configuration.ClientConfigPaths.GetEvidenceInfo(AppDomain appDomain, String exePath, String& typeName)
at System.Configuration.ClientConfigPaths.GetTypeAndHashSuffix(AppDomain appDomain, String exePath)
at System.Configuration.ClientConfigPaths..ctor(String exePath, Boolean includeUserConfig)
at System.Configuration.ClientConfigPaths.GetPaths(String exePath, Boolean includeUserConfig)
at System.Configuration.ClientConfigurationHost.RequireCompleteInit(IInternalConfigRecord record)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
at System.Configuration.ConfigurationManager.GetSection(String sectionName)
at System.Configuration.PrivilegedConfigurationManager.GetSection(String sectionName)
at System.DirectoryServices.SearchResultCollection.ResultsEnumerator..ctor(SearchResultCollection results, String parentUserName, String parentPassword, AuthenticationTypes parentAuthenticationType)
at System.DirectoryServices.SearchResultCollection.GetEnumerator()
at System.DirectoryServices.DirectorySearcher.FindOne()
at Utilities.ADUtilities.GetEnrollmentServiceByNameAndDNSName(String name, String dns_name) 

如果我使用相同的模拟上下文访问DirectoryEntry函数,或者使用不同的模拟上下文访问事件(撤消模拟并再次模拟),则不会抛出异常。

我想我找到问题了。我有一个CLI/c++ DLL作为我的c#项目的参考。如果我通过程序集加载DLL。在程序开始时加载LoadFile,那么问题就不会发生。另一方面,如果我让系统在它认为合适的时候加载它(系统似乎只在对DLL的实际调用完成时加载它),则会发生异常。

我在使用DirectoryEntry函数的相同方法中调用该DLL的方法。

例如:

void Method1()
{
    DirectoryEntry de = //....
    de. //....
   CLICPPLibrary.DoStuff();
}
无论如何,我认为这仍然是一个需要解决的问题。即使DLL稍后加载,也不应该有例外。或者至少在调用DirectoryEntry方法时不能发生异常。

相关内容

最新更新