Windows上使用本地用户帐户的基于PHP表单的身份验证

Windows上使用本地用户帐户的基于PHP表单的身份验证

PHP Forms-Based Authentication on Windows using Local User Accounts

我正在运行PHP,Apache和Windows。我没有域设置,所以我希望我网站的基于表单的身份验证使用Windows内置的本地用户帐户数据库(我认为它称为SAM)。

我知道,如果设置了Active Directory,则可以使用PHP LDAP模块在脚本中进行连接和身份验证,但是如果没有AD,就没有LDAP。独立计算机的等效功能是什么?


我也没有找到简单的解决方案。有使用CreateObject和WinNT ADSI提供程序的示例。但最终他们都碰上了
Active Directory服务接口WinNT提供程序的用户身份验证问题。我不确定100%,但是我想WSH /网络连接方法也有同样的问题。
根据如何在Microsoft操作系统上验证用户凭据,应使用LogonUser或SSPI。

它还说

1
2
3
LogonUser Win32 API does not require TCB privilege in Microsoft Windows Server 2003, however, for downlevel compatibility, this is still the best approach.

<p>On Windows XP, it is no longer required that a process have the SE_TCB_NAME privilege in order to call LogonUser. Therefore, the simplest method to validate a user's credentials on Windows XP, is to call the LogonUser API.</p>

因此,如果我确定不需要Win9x / 2000支持,我将编写一个扩展程序,将LogonUser暴露给php。
您可能还对NT帐户的用户身份验证感兴趣。它使用w32api扩展名,并且需要一个支持dll ...我宁愿写那个小的LogonUser-extension ;-)
如果那不可行,我可能会研究IIS的fastcgi模块及其稳定性,然后让IIS处理身份验证。

编辑:
我还尝试利用System.Security.Principal.WindowsIdentity和php的com / .net扩展名。但是dotnet构造函数似乎不允许将参数传递给对象构造函数,并且我的" experiment "从GetType()获取程序集(以及与之创建实例()一起使用)已失败,并出现了" unknown zval "错误。


构建PHP扩展需要大量的硬盘空间投资。由于我已经安装了GCC(MinGW)环境,因此决定采用从PHP脚本启动进程的性能。源代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 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源代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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>

好问题!

我已经考虑了一下……我想不出一个好的解决方案。我能想到的是一个可能可行的可怕骇客技巧。在看到将近一天没有人发布有关该问题的答案之后,我觉得很糟糕,但是可以解决问题。

在系统运行时,SAM文件超出范围。有一些DLL注入技巧可以使您工作,但最终您只会得到密码哈希,并且您必须对用户提供的密码进行哈希处理,以始终与它们匹配。

您真正想要的是一种尝试根据SAM文件对用户进行身份验证的东西。我认为您可以通过执行以下操作来做到这一点。

  • 在服务器上创建一个文件共享,并对其进行分配,以便仅授予您希望能够以其身份登录的帐户访问权限。
  • 在PHP中,使用system命令调用wsh脚本:使用网站用户提供的用户名和密码安装共享。记录驱动器是否正常运行,然后卸载驱动器。
  • 以某种方式收集结果。结果可以在脚本的stdout上返回给php,或者希望使用脚本的返回码返回。
  • 我知道它不漂亮,但是应该可以。

    我觉得很脏:|

    编辑:调用外部wsh脚本的原因是PHP不允许您使用UNC路径(据我所记得)。


    推荐阅读

      linux入侵网站命令?

      linux入侵网站命令?,工作,地址,信息,系统,数字,网站,名称,命令,网络,密码,lin

      linux命令中添加用户?

      linux命令中添加用户?,系统,密码,软件,用户,命令,信息,目录,用户名,账号,文

      linux命令更改用户?

      linux命令更改用户?,系统,密码,管理,用户,命令,环境,工作,地址,电脑,文件,lin

      linux命令创建用户组?

      linux命令创建用户组?,系统,代码,密码,用户组,用户,命令,信息,名称,新增,管

      linux命令给用户授权?

      linux命令给用户授权?,系统,数字,管理,权限,命令,密码,工具,时间,软件,信息,l

      linux命令创建用户组?

      linux命令创建用户组?,系统,代码,密码,用户组,用户,命令,信息,名称,新增,管

      查看linux用户命令行?

      查看linux用户命令行?,信息,系统,时间,名称,密码,用户,命令,地址,状态,设备,L

      linux所有用户命令行?

      linux所有用户命令行?,系统,信息,地址,工作,密码,命令,用户,时间,电脑,管理,L

      linux用户下的命令是?

      linux用户下的命令是?,系统,工作,管理,地址,命令,密码,基础,信息,目录,新增,L

      linux用户登录的命令?

      linux用户登录的命令?,系统,信息,工作,地址,时间,密码,名称,命令,电脑,软件,l

      linux关机用户命令?

      linux关机用户命令?,系统,工作,信息,状态,管理,命令,基础,目录,用户,功能,lin

      linux看用户信息命令?

      linux看用户信息命令?,系统,密码,信息,状态,软件,情况,命令,用户,网络,时间,l

      linux网站根目录命令?

      linux网站根目录命令?,系统,一致,设备,网站,目录,根目录,信息,标准,位置,电

      linux下删除用户命令?

      linux下删除用户命令?,系统,代码,邮箱,用户组,命令,用户,名称,管理,电脑,账

      用户id的linux命令?

      用户id的linux命令?,系统,密码,信息,联系方式,地址,位置,用户,命令,用户名,

      linux删除用户组命令?

      linux删除用户组命令?,管理,系统,密码,电脑,名称,用户,用户组,名字,信息,工

      linux锁定帐户的命令?

      linux锁定帐户的命令?,系统,密码,情况,管理,工作,用户,帐户,账户,命令,权限,L

      linux访问网站的命令?

      linux访问网站的命令?,地址,系统,服务,工作,网站,命令,网络,管理,信息,网址,L

      linux下用户权限命令?

      linux下用户权限命令?,管理,系统,密码,地址,权限,时间,基础,信息,基本知识,

      linux登陆用户命令?

      linux登陆用户命令?,系统,工具,信息,地址,软件,工作,命令,数字,服务,名称,Lin