문제

저는 PHP, Apache, Windows를 실행하고 있습니다.도메인 설정이 없으므로 웹 사이트의 양식 기반 인증에서 Windows에 내장된 로컬 사용자 계정 데이터베이스(SAM이라고 생각합니다)를 사용하고 싶습니다.

Active Directory가 설정되어 있으면 PHP LDAP 모듈을 사용하여 스크립트에 연결하고 인증할 수 있지만 AD가 없으면 LDAP가 없다는 것을 알고 있습니다.독립형 기계에 해당하는 것은 무엇입니까?

도움이 되었습니까?

해결책

나 역시 간단한 해결책을 찾지 못했다.CreateObject 및 WinNT ADSI 공급자를 사용하는 예가 있습니다.하지만 결국 다들 부딪히게 되고 Active Directory 서비스 인터페이스 WinNT 공급자의 사용자 인증 문제.100% 확신할 수는 없지만 나는 추측하다 WSH/네트워크 연결 접근 방식에도 동일한 문제가 있습니다.
에 따르면 Microsoft 운영 체제에서 사용자 자격 증명의 유효성을 검사하는 방법 LogonUser 또는 SSPI를 사용해야 합니다.
그것은 또한 말한다

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

Windows XP에서는 LogonUser를 호출하기 위해 더 이상 프로세스에 SE_TCB_NAME 권한이 필요하지 않습니다.따라서 Windows XP에서 사용자 자격 증명을 확인하는 가장 간단한 방법은 LogonUser API를 호출하는 것입니다.

그러므로 Win9x/2000 지원이 필요하지 않다고 확신한다면 LogonUser를 PHP에 노출시키는 확장을 작성하겠습니다.
당신은 또한에 관심이있을 수 있습니다 NT 계정에서 사용자 인증.w32api 확장을 사용하고 지원 dll이 필요합니다. 차라리 작은 LogonUser-extension을 작성하겠습니다 ;-)
이것이 가능하지 않다면 아마도 IIS용 fastcgi 모듈과 그것이 얼마나 안정적인지 살펴보고 IIS가 인증을 처리하도록 할 것입니다.

편집하다:
저도 활용해 봤습니다 System.Security.Principal.WindowsIdentity 그리고 PHP의 com/.net 확장자.그러나 dotnet 생성자는 개체 생성자에 매개 변수를 전달하는 것을 허용하지 않는 것 같으며 GetType()에서 어셈블리(및 CreateInstance())를 가져오기 위한 내 "실험"이 "알 수 없는 zval" 오류로 인해 실패했습니다.

다른 팁

좋은 질문!

이것저것 생각해봤는데...좋은 해결책이 생각나지 않네요.내가 생각할 수 있는 것은 작동할 수도 있는 끔찍하고 끔찍한 해킹입니다.거의 하루 동안 아무도 이 질문에 대한 답변을 게시하지 않은 것을 보고 나쁜 생각이 들었지만 제대로 작동하는 답변은 괜찮을 것이라고 생각했습니다.

시스템이 실행되는 동안 SAM 파일은 제한되지 않습니다.작동할 수 있는 몇 가지 DLL 주입 트릭이 있지만 결국에는 비밀번호 해시로 끝나고 어쨌든 일치하도록 사용자가 제공한 비밀번호를 해시해야 합니다.

당신이 정말로 원하는 것은 SAM 파일에 대해 사용자를 인증하려고 시도하는 것입니다.다음과 같은 작업을 수행하면 이 작업을 수행할 수 있다고 생각합니다.

  1. 서버에 파일 공유를 생성하고 로그인할 수 있는 계정에만 액세스 권한이 부여되도록 만드세요.
  2. PHP에서는 시스템 명령을 사용하여 다음과 같은 wsh 스크립트를 호출합니다.웹사이트 사용자가 제공한 사용자 이름과 비밀번호를 사용하여 공유를 마운트합니다.작동하는지 기록한 다음 작동하는 경우 드라이브를 마운트 해제합니다.
  3. 어떻게든 결과를 수집하세요.결과는 스크립트의 표준 출력에서 ​​또는 스크립트의 반환 코드를 사용하여 PHP로 반환될 수 있습니다.

나는 그것이 예쁘지 않다는 것을 알고 있지만 작동해야합니다.

더러워진 것 같아요 :|

편집하다:외부 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 ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top