C#通过模拟访问的DirectoryEntry将引发灾难性的例外,第一次只 [英] C# accessing DirectoryEntry via impersonation will throw a catastrophic exception for the first time only

查看:496
本文介绍了C#通过模拟访问的DirectoryEntry将引发灾难性的例外,第一次只的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的这个C#code冒充用户:

I am impersonating a user using this c# code:

    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将调用将访问Active Directory对象具有的DirectoryEntry(使用安全AuthenticationType)。该方法

Where invocation_delegate will call the method that will access Active Directory objects with DirectoryEntry (using Secure AuthenticationType).

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

My problem is that for the first time I invoke DirectoryEntry functionality, it throws the following exception:

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功能,则没有会抛出异常。

If I then access DirectoryEntry functions using the same impersonation context or event a different impersonation context (undo impersonation and impersonate again), then no exception will be thrown.

推荐答案

我认为,我发现这个问题。我有一个CLI / C ++ DLL。在我的C#项目的参考。如果我加载通过Assembly.LoadFile的DLL在节目的开始,那么这个问题就不会发生。如果在另一方面,我离开系统时,它认为合适的加载它(该系统似乎只加载它时,该DLL的实际调用完成),将发生异常。

I think that I found the problem. I have a CLI/C++ DLL as a reference in my C# project. If I load the DLL via Assembly.LoadFile at the start of the program, then the problem will not happen. If on the other hand, I leave the system to load it when it sees fit (The system seems to load it only when the actual call to the DLL is done), the the exception will occur.

我在打电话,我使用的DirectoryEntry功能的方法来此DLL中相同的方法。

I call methods to this DLL in the same method in which I use the DirectoryEntry functions.

例如:

void Method1()
{
    DirectoryEntry de = //....
    de. //....
   CLICPPLibrary.DoStuff();
}

无论如何,我认为这仍是需要修复的问题。即使该DLL稍后加载,应该没有例外。或者至少在调用的DirectoryEntry方法时,一定不要出现异常。

Anyway, I think this is still a problem that need to be fixed. Even if the DLL is loaded later, there should be no exception. Or at least the exception must not occur when calling the DirectoryEntry methods.

这篇关于C#通过模拟访问的DirectoryEntry将引发灾难性的例外,第一次只的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆