c# - 无法在 DLL 'LogonUser' 模拟异常中找到名为 'advapi32.dll' 的入口点

标签 c# asp.net impersonation

我在执行一些遗留模拟逻辑时遇到以下异常:

无法在 DLL“advapi32.dll”中找到名为“LogonUser”的入口点

我明白这个错误意味着我的应用程序在 advapi32.dll 中找不到 LogonUser 方法。

代码看起来像这样:

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String     lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);



if(LogonUser(_username, _domainname, _password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref _tokenHandle))
{
//do stuff...
}

有没有人遇到过类似的错误 - 关于如何修复它或为什么会发生的任何建议?除了使用 advapi32.dll(它是一个 .net 3.5 解决方案,但有很多遗留类)之外,还有更好的方法吗?

最佳答案

可能与“ExactSpelling = true”有关

这似乎可行:

public enum LogonType : int
{
    Interactive = 2,
    Network = 3,
    Batch = 4,
    Service = 5,
    Unlock = 7,
    NetworkCleartText = 8,
    NewCredentials = 9,
}

public enum LogonProvider : int
{  
    Default = 0,
}

public class Impersonation : IDisposable
{
    #region Dll Imports

    [DllImport("kernel32.dll")]
    private static extern Boolean CloseHandle(IntPtr hObject);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool LogonUser(string username, string domain,
                                          string password, LogonType logonType,
                                          LogonProvider logonProvider,
                                          out IntPtr userToken);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool DuplicateToken(IntPtr token, int impersonationLevel,
        ref IntPtr duplication);

          [DllImport("advapi32.dll", SetLastError = true)]
    static extern bool ImpersonateLoggedOnUser(IntPtr userToken);
    #endregion

    #region Private members

    private bool _disposed;

    private WindowsImpersonationContext _impersonationContext;

    #endregion

    #region Constructors

    public Impersonation(String username, String domain, String password)
    {
        IntPtr userToken = IntPtr.Zero;
        IntPtr userTokenDuplication = IntPtr.Zero;

        // Logon with user and get token.
        bool loggedOn = LogonUser(username, domain, password,
            LogonType.Interactive, LogonProvider.Default,
            out userToken);

        if (loggedOn)
        {
            try
            {
                // Create a duplication of the usertoken, this is a solution
                // for the known bug that is published under KB article Q319615.
                if (DuplicateToken(userToken, 2, ref userTokenDuplication))
                {
                    // Create windows identity from the token and impersonate the user.
                    WindowsIdentity identity = new WindowsIdentity(userTokenDuplication);
                    _impersonationContext = identity.Impersonate();
                }
                else
                {
                    // Token duplication failed!
                    // Use the default ctor overload
                    // that will use Mashal.GetLastWin32Error();
                    // to create the exceptions details.
                    throw new Exception("Could not copy token");
                }
            }
            finally
            {
                // Close usertoken handle duplication when created.
                if (!userTokenDuplication.Equals(IntPtr.Zero))
                {
                    // Closes the handle of the user.
                    CloseHandle(userTokenDuplication);
                    userTokenDuplication = IntPtr.Zero;
                }

                // Close usertoken handle when created.
                if (!userToken.Equals(IntPtr.Zero))
                {
                    // Closes the handle of the user.
                    CloseHandle(userToken);
                    userToken = IntPtr.Zero;
                }
            }
        }
        else
        {               
            throw new Exception("Login failed");
        }
    }

    ~Impersonation()
    {
        Dispose(false);
    }
    #endregion

    #region Public methods

    public void Revert()
    {
        if (_impersonationContext != null)
        {
            // Revert to previous user.
            _impersonationContext.Undo();
            _impersonationContext = null;
        }
    }
    #endregion

    #region IDisposable implementation.

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            Revert();

            _disposed = true;
        }
    }
    #endregion
}

关于c# - 无法在 DLL 'LogonUser' 模拟异常中找到名为 'advapi32.dll' 的入口点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6896539/

相关文章:

c# - 在 C# 中使用继承

c# - 如何在 yyyymmddhhmmss 中获取日期时间

asp.net - Active Directory LDS 异常

asp.net - 从 DropdownList SelectedItem 获取属性

c# - iTextSharp System.OutOfMemoryException 异常

c# 创建 thead 和 tbody

c# - Blazor 将数据绑定(bind)到集合?

.net - 如何获取调用进程 Windows 用户访问 token

powershell - 获取当前用户上下文

c# - 如何让 HttpClient 随请求一起传递凭据?