0

下面是我正在使用的一段代码。我可以使用 LogonType 9 和 Provider as 0(默认提供程序)来启动,但其他 Logon 类型(如 LogonType 4 或 5)不起作用。

我的 Windows Server 版本 MS Windows Server 2016 和用户已正确添加到 AdminL_LocalLogonAsBatchJob、AdminL_LocalLogonAsService 和 IIS_USRS 组中。

我可能错过了什么?

public class Impersonate
{

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern int LogonUser(IntPtr lpszUsername, IntPtr lpszDomain, IntPtr lpszPassword,
                                        int dwLogonType, int dwLogonProvider, out int phToken);

    [DllImport("kernel32.dll")]
    private static extern int FormatMessage(int dwFlags, string lpSource, int dwMessageId, int dwLanguageId,
                                            StringBuilder lpBuffer, int nSize, string[] Arguments);



    private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;

    private static WindowsImpersonationContext winImpersonationContext = null;

    public static string ImpersonateUser(string domain, string userName, string password, int logonType, int provider)
    {


        string msg = string.Empty;

        IntPtr UserNamePointer = IntPtr.Zero;
        IntPtr PasswordPointer = IntPtr.Zero;
        IntPtr DomainNamePointer = IntPtr.Zero;


        UserNamePointer = Marshal.SecureStringToGlobalAllocUnicode(ConvertToSecureString(userName));
        PasswordPointer = Marshal.SecureStringToGlobalAllocUnicode(ConvertToSecureString(password));
        DomainNamePointer = Marshal.SecureStringToGlobalAllocUnicode(ConvertToSecureString(domain));

        bool loggedOn = (LogonUser((IntPtr)UserNamePointer, (IntPtr)DomainNamePointer, (IntPtr)PasswordPointer, logonType,
                                    provider, out int userToken) != 0);

        if (loggedOn == false)
        {
            int apiError = Marshal.GetLastWin32Error();
            StringBuilder errorMessage = new StringBuilder(1024);
            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, null, apiError, 0, errorMessage, 1024, null);
            msg = errorMessage.ToString();
        }
        else
        {
            msg = "Logged On True";
        }
        if (userToken != 0)
        {
            WindowsIdentity identity = new WindowsIdentity((IntPtr)userToken);
            winImpersonationContext = identity.Impersonate();
        }


        return msg;
    }
    private static SecureString ConvertToSecureString(string password)
    {
        if (password == null)
            throw new ArgumentNullException("password");

        var securePassword = new SecureString();

        foreach (char c in password)
            securePassword.AppendChar(c);

        securePassword.MakeReadOnly();
        return securePassword;
    }
    public static void UndoImpersonation()
    {
        if (winImpersonationContext != null)
        {
            winImpersonationContext.Undo();
        }
    }

}
4

0 回答 0