我正在运行PHP,Apache和Windows。 我没有域设置,所以我想我的网站的基于窗体的身份validation使用内置到Windows(本人认为这就是所谓的SAM)本地用户帐户数据库。
我知道,如果安装了Active Directory,则可以使用PHP LDAP模块在您的脚本中进行连接和身份validation,但是如果没有AD,则不会有LDAP。 什么是独立机器的等价物?
我还没有找到一个简单的解决方案。 有一些使用CreateObject和WinNT ADSI提供程序的示例。 但最终他们都遇到与Active Directory服务接口WinNT提供程序的用户身份验证问题 。 我不是100%确定,但我想 WSH /网络连接方法也有同样的问题。
根据如何验证Microsoft操作系统上的用户凭据,您应该使用LogonUser或SSPI。
它也说
LogonUser Win32 API不需要Microsoft Windows server 2003中的TCB权限,但是,对于低级别兼容性,这仍然是最好的方法。
在Windows XP上,进程不再需要具有SE_TCB_NAME特权才能调用LogonUser。 因此,在Windows XP上验证用户凭据的最简单方法是调用LogonUser API。 因此,如果我确定不需要Win9x / 2000的支持,我会写一个扩展,将LogonUser公开给php。
您可能也有兴趣从NT帐户的用户身份验证 。 它使用w32api扩展名,并需要一个支持DLL …我宁愿写这个小的LogonUser-扩展名;-)
如果这是不可行的,我可能会考虑IIS的fastcgi模块,它是多么稳定,让IIS处理身份验证。
编辑:
我也尝试过使用System.Security.Principal.WindowsIdentity和php的com / .net扩展名 。 但dotnet构造函数似乎不允许传递参数给对象的构造函数,而我的“实验”从GetType()获取程序集(以及它的CreateInstance())失败,出现“unknown zval”错误。
好问题!
我给了这个想法…我想不出一个好的解决方案。 我能想到的是一个可怕的可怕的黑客,可能会工作。 看到没有人回答这个问题近一天,我觉得不好,但工作的答案是可以的。
在系统运行时,SAM文件是关闭的。 有一些DLL注入技巧,你可能能够得到工作,但最终你会只是密码哈希,你必须哈希用户提供的密码来匹配他们。
你真正想要的是试图验证用户对SAM文件的东西。 我想你可以通过做下面的事情来做到这一点。
我知道这不是很好,但它应该工作。
我觉得很脏:|
编辑:调用外部wsh脚本的原因是,PHP不允许你使用UNC路径(据我所知)。
构建PHP扩展需要在硬盘空间方面进行相当大的投资。 由于我已经安装了GCC(MinGW)环境,我决定从PHP脚本中启动一个进程的性能。 源代码如下。
// Usage: logonuser.exe /user username /password password [/domain domain] // Exit code is 0 on logon success and 1 on failure. #include <windows.h> int main(int argc, char *argv[]) { HANDLE r = 0; char *user = 0; char *password = 0; char *domain = 0; int i; for(i = 1; i < argc; i++) { if(!strcmp(argv[i], "/user")) { if(i + 1 < argc) { user = argv[i + 1]; i++; } } else if(!strcmp(argv[i], "/domain")) { if(i + 1 < argc) { domain = argv[i + 1]; i++; } } else if(!strcmp(argv[i], "/password")) { if(i + 1 < argc) { password = argv[i + 1]; i++; } } } if(user && password) { LogonUser(user, domain, password, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &r); } return r ? 0 : 1; }
接下来是展示其使用的PHP源代码。
if($_SERVER['REQUEST_METHOD'] == 'POST') { if(isset($_REQUEST['user'], $_REQUEST['password'], $_REQUEST['domain'])) { $failure = 1; $user = $_REQUEST['user']; $password = $_REQUEST['password']; $domain = $_REQUEST['domain']; if($user && $password) { $cmd = "logonuser.exe /user " . escapeshellarg($user) . " /password " . escapeshellarg($password); if($domain) $cmd .= " /domain " . escapeshellarg($domain); system($cmd, $failure); } if($failure) { echo("Incorrect credentials."); } else { echo("Correct credentials!"); } } } ?> <form action="<?php echo(htmlentities($_SERVER['PHP_SELF'])); ?>" method="post"> Username: <input type="text" name="user" value="<?php echo(htmlentities($user)); ?>" /><br /> Password: <input type="password" name="password" value="" /><br /> Domain: <input type="text" name="domain" value="<?php echo(htmlentities($domain)); ?>" /><br /> <input type="submit" value="logon" /> </form>