本地机器的模拟在它应该失败时成功
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测试失败,但在本地模拟器上工作