本应失败的本地机器模拟成功

本文关键字:模拟 成功 机器 失败 | 更新日期: 2023-09-27 18:11:51

问题:

我有一个windows服务,它使用模拟来检查单独服务器上的服务状态,但是在测试期间注意到,当用户提供本地机器地址和无效的本地机器帐户时,检查将继续打开服务控制管理器并成功检索状态。我们的目标是让它只与有效的本地机器帐户一起工作。

代码:模拟名称空间(包含用于设置模拟的方法(SoddingNetworkAuth):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.Principal;
namespace Impersonation
{
  public class Network
  {
    public class SoddingNetworkAuth : IDisposable
    {
      [DllImport("advapi32.dll", SetLastError = true)]
      private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
      [DllImport("kernel32", SetLastError = true)]
      private static extern bool CloseHandle(IntPtr hObject);
      private IntPtr userHandle = IntPtr.Zero;
      private WindowsImpersonationContext impersonationContext;
      public SoddingNetworkAuth(string user, string domain, string password)
      {
        if (!string.IsNullOrEmpty(user))
        {
          // Call LogonUser to get a token for the user  
          bool loggedOn = LogonUser(user, domain, password,
                          9 /*(int)LogonType.LOGON32_LOGON_NEW_CREDENTIALS*/,
                          3 /*(int)LogonProvider.LOGON32_PROVIDER_WINNT50*/,
          out userHandle);
          if (!loggedOn)
            throw new Win32Exception(Marshal.GetLastWin32Error());
          // Begin impersonating the user  
          impersonationContext = WindowsIdentity.Impersonate(userHandle);
        }
      }
      public void Dispose()
      {
        if (userHandle != IntPtr.Zero)
          CloseHandle(userHandle);
        if (impersonationContext != null)
          impersonationContext.Undo();
      }
    }
  }
}

我为测试编写的控制台应用程序:

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceProcess;

namespace NetworkAuthIssue
{
    class Program
    {
        static void Main(string[] args)
        {
            string result;
            try
            {
                using (new Impersonation.Network.SoddingNetworkAuth("Invalid User", "localhost", "InvalidPassword"))
                {
                    var serviceController = new ServiceController("Power", "localhost");
                    if (serviceController.Status == ServiceControllerStatus.Running)
                    {
                        result = "Authenticated, service running";
                    }
                    else
                    {
                        result = "Authenticated, service not running";
                    }
                }
            }
            catch (Exception e)
            {
                result = "Authentication Failed";
            }
            Console.WriteLine(result);
            Console.Read();
        }
    }
}

我正在运行Windows 8.1

本应失败的本地机器模拟成功

这是因为你使用的是LOGON32_LOGON_NEW_CREDENTIALS

来自https://msdn.microsoft.com/en-us/library/windows/desktop/aa378184%28v=vs.85%29.aspx(强调我的):

此登录类型允许调用方克隆其当前令牌并为出站连接指定新的凭据。新的登录会话具有相同的本地标识符,但对其他网络连接使用不同的凭据。

"出站连接"部分很重要。这意味着对于本地连接,所提供的凭据根本不会被使用。当前标识用于本地连接。

我现在不能检查事情,但我有类似的问题像你,这是由选择的LogonType/LogonProvider值在登录方法引起的。你应该在控制台应用程序中尝试它们,并使用适合你的场景的组合。

请参见此方法的msdn文档:https://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx