验证本地 Windows 用户帐户
Authenticate Local Windows User Accounts
我编写了这个 JScript 来验证本地 Windows 用户帐户:
function ValidateCredentials(strUsername, strPassword) {
var ADS_SECURE_AUTHENTICATION = 1;
var objWMISvc = GetObject("winmgmts:\\.\root\cimv2");
var colItems = objWMISvc.ExecQuery( "Select * from Win32_ComputerSystem");
for (var it = new Enumerator(colItems); !it.atEnd(); it.moveNext()) {
var objItem = it.item();
if (objItem.PartOfDomain)
continue;
var strWorkgroup = objItem.Domain;
var strComputer = objItem.Name;
var strPath = "WinNT://" + strWorkgroup + "/" + strComputer + "/" +
strUsername + ",user";
try {
var objIADS = GetObject("WinNT:").OpenDSObject(strPath, strUsername,
strPassword, ADS_SECURE_AUTHENTICATION);
WScript.Echo("OK");
} catch(e) {
WScript.Echo("Invalid Username/Password");
}
}
}
ValidateCredentials(WScript.Arguments(0), WScript.Arguments(1));
当我从命令提示符 运行 它工作正常,无论是作为管理员还是普通用户。当服务进程 运行ning 作为 LocalSystem 用户调用该脚本时,它不起作用。相反,对 OpenDSObject 的调用会引发错误代码为 -2147023584 的异常(指定的登录会话不存在。它可能已经终止)。
这里有什么问题,我认为 LocalSystem 帐户实际上比管理员帐户更有特权或更受信任?
您可以自己试用该脚本,方法是将它保存到某个 .js 文件中,然后 运行 从命令提示符下运行该脚本,如下所示:
cscript.exe validate.js myUsername myPassword
如果您只想验证密码,我会避免上述所有操作。有一种稍微不同的方法可以很好地用于非特权帐户。事实上,您想要确保该帐户实际上没有更改密码的权利。
使用此方法,您调用 NetUserChangePassword
,这要求您指定用户的现有密码,以便在更改之前进行身份验证。
当您从无权更改该用户密码的帐户执行此操作时,显然会失败(因此他们的密码不会更改)。我们关心的正是如何失败。如果返回 ERROR_INVALID_PASSWORD
失败,那么您就知道密码是错误的。如果返回 ERROR_ACCESS_DENIED
失败,则密码正确,并且函数失败,因为您从中调用它的帐户无权更改该用户的密码。
因此,不需要像 LocalSystem 或管理员这样的高权限帐户,这允许您从一个基本上没有任何权限的帐户(强烈偏好,甚至没有更改自己的密码的权利) ).
我编写了这个 JScript 来验证本地 Windows 用户帐户:
function ValidateCredentials(strUsername, strPassword) {
var ADS_SECURE_AUTHENTICATION = 1;
var objWMISvc = GetObject("winmgmts:\\.\root\cimv2");
var colItems = objWMISvc.ExecQuery( "Select * from Win32_ComputerSystem");
for (var it = new Enumerator(colItems); !it.atEnd(); it.moveNext()) {
var objItem = it.item();
if (objItem.PartOfDomain)
continue;
var strWorkgroup = objItem.Domain;
var strComputer = objItem.Name;
var strPath = "WinNT://" + strWorkgroup + "/" + strComputer + "/" +
strUsername + ",user";
try {
var objIADS = GetObject("WinNT:").OpenDSObject(strPath, strUsername,
strPassword, ADS_SECURE_AUTHENTICATION);
WScript.Echo("OK");
} catch(e) {
WScript.Echo("Invalid Username/Password");
}
}
}
ValidateCredentials(WScript.Arguments(0), WScript.Arguments(1));
当我从命令提示符 运行 它工作正常,无论是作为管理员还是普通用户。当服务进程 运行ning 作为 LocalSystem 用户调用该脚本时,它不起作用。相反,对 OpenDSObject 的调用会引发错误代码为 -2147023584 的异常(指定的登录会话不存在。它可能已经终止)。
这里有什么问题,我认为 LocalSystem 帐户实际上比管理员帐户更有特权或更受信任?
您可以自己试用该脚本,方法是将它保存到某个 .js 文件中,然后 运行 从命令提示符下运行该脚本,如下所示:
cscript.exe validate.js myUsername myPassword
如果您只想验证密码,我会避免上述所有操作。有一种稍微不同的方法可以很好地用于非特权帐户。事实上,您想要确保该帐户实际上没有更改密码的权利。
使用此方法,您调用 NetUserChangePassword
,这要求您指定用户的现有密码,以便在更改之前进行身份验证。
当您从无权更改该用户密码的帐户执行此操作时,显然会失败(因此他们的密码不会更改)。我们关心的正是如何失败。如果返回 ERROR_INVALID_PASSWORD
失败,那么您就知道密码是错误的。如果返回 ERROR_ACCESS_DENIED
失败,则密码正确,并且函数失败,因为您从中调用它的帐户无权更改该用户的密码。
因此,不需要像 LocalSystem 或管理员这样的高权限帐户,这允许您从一个基本上没有任何权限的帐户(强烈偏好,甚至没有更改自己的密码的权利) ).