问题:
我有 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/