本应失败的本地机器模拟成功
本文关键字:模拟 成功 机器 失败 | 更新日期: 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