Domanda

Utilizzo PHP, Apache e Windows.Non ho una configurazione di dominio, quindi vorrei che l'autenticazione basata su moduli del mio sito Web utilizzasse il database degli account utente locali integrato in Windows (penso che si chiami SAM).

So che se è configurato Active Directory, puoi utilizzare il modulo LDAP PHP per connetterti e autenticarti nel tuo script, ma senza AD non c'è LDAP.Qual è l'equivalente per le macchine autonome?

È stato utile?

Soluzione

Neanche io ho trovato una soluzione semplice.Esistono esempi che utilizzano CreateObject e il provider WinNT ADSI.Ma alla fine si scontrano tutti Problemi di autenticazione dell'utente con il provider WinNT di Active Directory Service Interfaces.Non ne sono sicuro al 100% ma io Indovinare l'approccio WSH/connessione di rete presenta lo stesso problema.
Secondo Come convalidare le credenziali dell'utente sui sistemi operativi Microsoft dovresti usare LogonUser o SSPI.
Dice anche

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

In Windows XP non è più necessario che un processo disponga del privilegio SE_TCB_NAME per chiamare LogonUser.Pertanto, il metodo più semplice per convalidare le credenziali di un utente su Windows XP consiste nel chiamare l'API LogonUser.

Pertanto, se fossi certo che il supporto Win9x/2000 non sia necessario, scriverei un'estensione che esponga LogonUser a php.
Potrebbe anche interessarti Autenticazione utente da account NT.Utilizza l'estensione w32api e necessita di una DLL di supporto...Preferirei scrivere quella piccola estensione LogonUser ;-)
Se ciò non è fattibile, probabilmente esaminerei il modulo fastcgi per IIS e quanto sia stabile e lascerei che IIS gestisca l'autenticazione.

modificare:
Ho anche provato a utilizzare System.Security.Principal.WindowsIdentity e php estensione com/.net.Ma il costruttore dotnet non sembra consentire il passaggio di parametri al costruttore di oggetti e il mio "esperimento" per ottenere l'assembly (e con esso CreateInstance()) da GetType() non è riuscito con un errore "zval sconosciuto".

Altri suggerimenti

Buona domanda!

Ci ho pensato un po'...e non riesco a pensare ad una buona soluzione.Quello a cui riesco a pensare è un trucco orribile che potrebbe funzionare.Dopo aver visto che nessuno ha pubblicato una risposta a questa domanda per quasi un giorno, ho pensato che una risposta negativa, ma funzionante, sarebbe stata ok.

Il file SAM è vietato mentre il sistema è in esecuzione.Ci sono alcuni trucchi di DLL Injection che potresti riuscire a far funzionare, ma alla fine ti ritroverai con gli hash delle password e dovresti comunque eseguire l'hashing delle password fornite dall'utente per confrontarle con esse.

Ciò che vuoi veramente è qualcosa che tenti di autenticare l'utente rispetto al file SAM.Penso che tu possa farlo facendo qualcosa di simile al seguente.

  1. Crea una condivisione file sul server e fai in modo che solo gli account a cui desideri poter accedere abbiano accesso ad essa.
  2. In PHP utilizzare il comando di sistema per invocare uno script wsh che:monta la condivisione utilizzando il nome utente e la password forniti dall'utente del sito Web.registra se funziona e quindi smonta l'unità se funziona.
  3. Raccogli il risultato in qualche modo.Il risultato può essere restituito a php sullo stdout dello script o, si spera, utilizzando il codice di ritorno per lo script.

So che non è carino, ma dovrebbe funzionare.

Mi sento sporco :|

Modificare:il motivo per invocare lo script wsh esterno è che PHP non ti consente di utilizzare percorsi UNC (per quanto ricordo).

Costruire un'estensione PHP richiede un investimento piuttosto elevato in termini di spazio su disco rigido.Dato che ho già installato l'ambiente GCC (MinGW), ho deciso di sfruttare le prestazioni lanciando un processo dallo script PHP.Il codice sorgente è sotto.

// 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;
}

Poi c'è il sorgente PHP che ne dimostra l'utilizzo.

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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top