c# - 模拟本地计算机在应该失败时成功

标签 c# impersonation

问题:

我有 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 (强调我的):

This logon type allows the caller to clone its current token and specify new credentials for outbound connections. The new logon session has the same local identifier but uses different credentials for other network connections.

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

关于c# - 模拟本地计算机在应该失败时成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32483046/

相关文章:

c# - 如何使用 P/Invoke 在 C# 中返回列表?

asp.net - 如何从 ASP.NET 应用程序启动/停止 Windows 服务 - 安全问题

c# - 未将凭据传递给 WCF 服务导致 401

c++ - 使用 C++ 程序的新 GPO

c# - 更新 Dynamics 发票详细信息实体时出现 InvalidCastException

c# - SQL 异常错误 C# ASP.Net

C# 7.0 元组推导

c# - 何时使用哈希表

wcf - 如何模拟 WCF 服务的用户?

c# - 如何检查Windows用户是否可以通过模拟访问(Windows集成安全性身份验证)SQL Server Analysis Services(SSAS)服务器