Search code examples
phpwindowsapacheauthenticationsam

PHP Forms-Based Authentication on Windows using Local User Accounts


I'm running PHP, Apache, and Windows. I do not have a domain setup, so I would like my website's forms-based authentication to use the local user accounts database built in to Windows (I think it's called SAM).

I know that if Active Directory is setup, you can use the PHP LDAP module to connect and authenticate in your script, but without AD there is no LDAP. What is the equivalent for standalone machines?


Solution

  • I haven't found a simple solution either. There are examples using CreateObject and the WinNT ADSI provider. But eventually they all bump into User authentication issues with the Active Directory Service Interfaces WinNT provider. I'm not 100% sure but I guess the WSH/network connect approach has the same problem.
    According to How to validate user credentials on Microsoft operating systems you should use LogonUser or SSPI.
    It also says

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

    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.

    Therefore, if I were certain Win9x/2000 support isn't needed, I would write an extension that exposes LogonUser to php.
    You might also be interested in User Authentication from NT Accounts. It uses the w32api extension, and needs a support dll ...I'd rather write that small LogonUser-extension ;-)
    If that's not feasible I'd probably look into the fastcgi module for IIS and how stable it is and let the IIS handle the authentication.

    edit:
    I've also tried to utilize System.Security.Principal.WindowsIdentity and php's com/.net extension. But the dotnet constructor doesn't seem to allow passing parameters to the objects constructor and my "experiment" to get the assembly (and with it CreateInstance()) from GetType() has failed with an "unknown zval" error.