[英]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提供商的用戶身份驗證問題 。 the WSH/network connect approach has the same problem. 我不是100%肯定,但我 WSH /網絡連接方法有同樣的問題。
根據如何在Microsoft操作系統上驗證用戶憑據,您應該使用LogonUser或SSPI。
它還說
因此,如果我確定不需要Win9x / 2000支持,我會編寫一個將LogonUser暴露給php的擴展。LogonUser Win32 API在Microsoft Windows Server 2003中不需要TCB權限,但是,對於下層兼容性,這仍然是最好的方法。 \n\n在Windows XP上,不再需要進程具有SE_TCB_NAME權限才能調用LogonUser。 因此,在Windows XP上驗證用戶憑據的最簡單方法是調用LogonUser API。
編輯:
我也嘗試過使用System.Security.Principal.WindowsIdentity和php的com / .net擴展名 。 但是dotnet構造函數似乎不允許將參數傳遞給對象構造函數,而我的“實驗”從GetType()獲取程序集(以及它的CreateInstance())失敗並出現“未知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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.