Why you’d ever want to do this is probably a discussion best left to the political arena. But for the purpose of that thing I call my “day job”, I was required to do just this.
External website, authenticates against Active Directory using LDAPS. Website is coded in PHP, and runs on IIS on Windows Server 2008 R2 x64.
In the rest of the world, this is an Apache deal, but limited by internal support, it has to be IIS and Windows.
Requirements to make this work:
- Active Directory domain controller (DC), configured as an Enterprise Certification Authority
- Firewall opened from web server to DC on either TCP port 636 or 3269 (3269 is the LDAPS port for a Global Catalog)
- Windows Server (I’d say any of the 2003/2008 versions will work)
- IIS (6 or 7)
- PHP (I’m using version 5.3.6) with the php_ldap extension
Getting there:
- Configure AD OU’s / security groups to suit your application
- Generate a Root CA certificate for your domain/domain controllers
- Export the Root CA in Base64 X.509 format
- Copy Root CA certificate to the webserver (C:\OpenLDAP\sysconf\webcert.crt)
- Create C:\OpenLDAP\sysconf\ldap.conf with the following lines:
TLS_REQCERT never
TLS_CACERT c:\openldap\sysconf\webcert.crt - Install PHP on the webserver, using the IIS FastCGI installer option, and enabling the LDAP extension (if you use the installer, that is. If you do a manual install, you have to install/configure these manually.)
- Use ldap_connect(“ldaps://servername//”) to connect – if using the global catalog, specify the port in the URL, i.e. ldaps://servername:3269
Code:
<?php
$ds=ldap_connect("ldaps://servername/");
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
$ldapbind = @ldap_bind($ds, "[email protected]", "password");
if($ldapbind) {
// do some stuff
} else {
echo ldap_error();
}
ldap_close($ds);
?>
Final Notes:
Provided all is done as above, should be able to connect to LDAPS perfectly. Use “ldp.exe” to check LDAP connectivity using SSL (use port 636 or 3269 – not 389 as is the default), or any other LDAP tool that supports LDAP with SSL.
I got caught out exporting the Root CA certificate from the certificate store as a DER Encoded X.509 certificate, instead of Base64. Yes, it matters.
There is very little documentation for this solution – specifically the certificate requirements. LDAPS in generally is supported quite well, as is configuring Active Directory to serve up LDAPS. Even the PHP coding is well supported. The Windows/IIS/PHP/LDAPS combination as a whole, however, is best documented…right here, of course 🙂
Lastly – there’s a bug in some versions of the PHP LDAP module (5.3.3 I believe fixed it), which required you to place the ldap.conf file at the root of every drive that hosts an IIS website – or, just the one that utilises the LDAP file. I haven’t tested this, but it is discussed very briefly on some of the PHP threads I found.
Important links:
- http://adldap.sourceforge.net/
- http://php.net/manual/en/function.ldap-start-tls.php
Can you explain me about OpenLDAP?, Do you install the software on the server or do you just create the folder? I miss that part in your wonderful explanation.
Greetings
No need to install OpenLDAP if I recall, just create the directories as posted 🙂
I tried following your solution. For some reason, LDAPS still fails despite successfully connecting via ldp.exe to all ports. I just resolved another issue of simply being able to enable ldaps (http://serverfault.com/questions/445397/binding-to-ldaps-using-php-failing/445507#comment482850_445507). I appreciate your help.
Hi Sean, the biggest issue I found was exporting the certificate in the right format. It’s very easy to miss this! Do you get any errors logged?
hi i have got a little problem with the “Generate a Root CA certificate for your domain/domain controllers”-Part. I can use ldap via ssl with the ldp.exe out of the box (new test-activedirectory) but i cant use it with php. as far as i understand it, there have to exist a certificate already, cause ldaps works, but i dont know where to export it or create an new one.
can you help me or give any hint?
Thanks for this. It almost worked. Only missing part was converting cer to pem.
http://greg.cathell.net/php_ldap_ssl.html
Then worked great. I didn’t need to copy the .dll to the windows\system32.
This was on 2008R2. The whole openssll folder path is odd
Also had to enable php_openssl in php.ini.
I figured this process out myself in 2011 for a project. Now I’m replacing that server and need to do it again. Obviously, I didn’t document my steps. I was missing the OpenSSL part. It only took a week of searching to stumble across your page. Thank you for putting this out there.