本地机器的模拟在它应该失败时成功

Posted

技术标签:

【中文标题】本地机器的模拟在它应该失败时成功【英文标题】:Impersonation for Local Machine Succeeding when it should fail 【发布时间】:2015-09-09 14:59:42 【问题描述】:

问题:

我有使用模拟检查单独服务器上的服务状态的 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

【问题讨论】:

【参考方案1】:

这是因为您使用的是LOGON32_LOGON_NEW_CREDENTIALS

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

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

“出站连接”部分很重要。这意味着对于本地连接,根本不使用提供的凭据。当前身份用于本地连接。

【讨论】:

【参考方案2】:

我现在无法检查,但我遇到了类似的问题,这是由 Logon 方法中选择的 LogonType/LogonProvider 值引起的。您应该在控制台应用程序中试用它们并使用适合您的场景的组合。

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

【讨论】:

以上是关于本地机器的模拟在它应该失败时成功的主要内容,如果未能解决你的问题,请参考以下文章

加载本地化 pathForResource 在 iOS 模拟器上工作,但在设备上失败

机器人框架模拟器 - 在本地部署机器人并安装在团队中

Travis CI AVD上的Android Instrumentation测试失败,但在本地模拟器上工作

访问 Cloud Functions Firebase CLI 本地模拟器中的配置变量失败

vs2022创建模拟器失败

在将本地机器人连接到本地 WebChat 客户端时获取 403(尽管适用于模拟器)