PHP LDAP LOGIN

PHP on Linux authenticate users with a Windows Server Active Directory

A common request when building INTRANET web applications is to have users use only one common shared set of login credentials. Typically in most small and medium businesses this means that logging into a Windows Server of some kind to access the network. Windows Servers use Active Directory (AD) ,which is basically Microsoft’s glorified LDAP server with a slew of additional features needed for coroporate and enterprise users. We can leverage this by using PHP’s LDAP module to perform the login check for us..

IF you’re building your application in PHP a very easy way to do this is simply to use PHPs LDAP library and then simply call with the proper functions. Let’s detail the steps below. I’ll be doing this from a PHP 5 , Debian installation.

LDAP tends to be tied into the Windows AD Domain Name System to allow integrated quick lookups and fast resolution of queries. LDAP generally runs on port 389 and like other protocols tends to usually conform to a distinct set of rules (RFC’s).

Читайте также:  Reconnect to server java

Step 1. Get the LDAP information (LDAP Connection URL) from your Windows Active Directory.

First we need to verify which Windows Active directory we will be authenticating against. If your in a very large corporate environment, you may need the help of an SA (System administrator) to help guide you. Basically, the first thing you need is to know is the Domain which this users is associated with.

Essetially you need to figure out with the LDAP Connection URL is , and this requires a bit more information about how the Windows Network is configured, Typically its something like ,

CN=Users,DC=corp,DC=domain,DC=local

then you wold combine this with the URL of the Windows AD server

LDAP://dc1.corp.domain.com/ or LDAP://10.0.1.3/

To query for a particular user. If you have accesss to the Windows Server form the command line run.

C:\Users\Administrator> dsquery user -name To* "CN=Tony Jones,CN=Users,DC=Domain,DC=local" "CN=Tony Smith,CN=Users,DC=Domain,DC=local"

Alternatively from the Windows server desktop try

Active directory server -> Choose the Organization Unit OU -> Right Click -> Properties -> AttributeEditor -> DistinguishedName

The above information is necessary so you can fill in the details of the PHP script below.

Step 2. Verify PHP LDAP Library installed and enabled.

You can do this by running a simple viewing the PHP info to see which loaded modules are currently available on your server.

Create a simple PHP file on your web server , call it test.php or something like that. When you run it it will display all the information that PHP /Apache has configured.

Run that file from your browser http://localhost/test.php and search for an entry like LDAP (Typically midway down the page between JSON and LIBXML ), if you see something like the screen below.

PHP info showing LDAP module is enabled.

If you do not see this enabled, then you may want to have it added to your PHP/Apache server . The simplest way if you have a typical Debian Linux access to your server’s shell is to run the command. For other flavors of Linux like Redhat/Centos a similar yum command should be available.

sudo apt-get install php5-ldap
sudo apt-get install php-ldap

The command should install the necessary library and restart the server, once again re-test that it’s enabled by running the above test.php and confirming the LDAP module is correctly loaded.

Step 3. Test PHP Login against Windows AD

Finally Upload this test LDAP script to your server and save it as ldap.php (or similar name) which does the follow…

  • Usig the supplied LDAP information , don’t forget to REPLACE the DOMAIN_FQDN and LDAP_SERVER define with your actual credentials
  • Takes the user supplied username and password and
  • Issues an LDAP bind to see if that’s a valid user
  • You get back either a True or False from the AD and you can proceed from there.
 elseif ($bind) < //determine the LDAP Path from Active Directory details $base_dn = array("CN=Users,DC=". join(',DC=', explode('.', DOMAIN_FQDN)), "OU=Users,OU=People,DC=". join(',DC=', explode('.', DOMAIN_FQDN))); $result = ldap_search(array($conn,$conn), $base_dn, "(cn=*)"); if (!count($result)) $err = 'Result: '. ldap_error($conn); else < echo "Success"; /* Do your post login code here */ >> > // session OK, redirect to home page if (isset($_SESSION['redir'])) < header('Location: /'); exit(); >elseif (!isset($err)) $err = 'Result: '. ldap_error($conn); ldap_close($conn); > ?>     

Login

'; ?> Password:
'. $err .'
Login:

Security Considerations:

By default, LDAP traffic is transmitted unsecured; this may or may not be a concern in an Intranet setting, for maximum safety use SSL technology to encrypt the traffic. Also most Windows Server AD will LOCK the account after n unsuccessful re-tries so be aware of this when testing your PHP login script.

Hopefully this will provide an easy way to integrate your PHP scripts with your INTRANET servers, making it easier to keep manage user accounts and access from one spot.

11 thoughts on “ PHP on Linux authenticate users with a Windows Server Active Directory ”

Thanks, this works far better than any other process I’ve seen and takes far less configuration. Obviously we need to set up sessions with this but this is a great starting point. I should note on line 80 you are missing a closing bracket.

Is any option to check if user can login or what kind of user we have – without getting username and password? By using some “server variable”, “server user id”, “server user login”, “server user fingerprint”? Our goal is that when user is opening website on localhost we know that this in “Mark Twain” ex. and we have nice screen for him – without username and password.

I think you should be able to query the ACTIVE Directory server as to USER ATTRIBUTES, this does require that the folks that created the account properly assigned those attributes. Take a look here at some attributes available on active driectory http://www.kouti.com/tables/userattributes.htm . Once you have gotten the attribute for a user then you can decide what to show. I know most companies don’t add any extra attributes, besides maybe the department or description , maybe you can key off those two.?

Similar to the commend about a missing bracket on line 80…The code is missing a closing angle bracket for the tr tag (>) on line 85. Maybe it was originally line 80 and is now line 85.

Источник

Подключение к AD из PHP по протоколу LDAPS

Прочитав пост Создаем пользователя AD через веб-интерфейс, вспомнил, что около года назад занимался с аналогичной задачей. Проблема была в том, что не удавалось создать пользователя при соединении по протоколу LDAP, а получилось только по протоколу LDAPS. Выкладываю свои записи, вдруг кому пригодится.

Все действия проделывались в RHEL 5.5 и Windows Server 2003 R2 EE.

Сертификаты
rpm -ivh openssl-0.9.8e-12.el5_4.6.i686.rpm rpm -ivh openssl-perl-0.9.8e-12.el5_4.6.i386.rpm
dir = /root/sslCA default_days = 3650 countryName_default = UA stateOrProvinceName_default = Lugansk localityName_default = Lugansk 0.organizationName_default = CompanyName organizationalUnitName_default = IT . # в конце файла [ sign_ias_csr ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = clientAuth,serverAuth 
cd /root/ mkdir sslCA chmod 700 sslCA cd /root/sslCA mkdir certs private newcerts echo 1000 > serial touch index.txt openssl req -new -x509 -days 3650 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -config /etc/pki/tls/openssl.cnf 
Сертификаты для контроллеров домена
#!/bin/sh NAME=$1 BITS=1024 CONFIG=/etc/pki/tls/openssl.cnf # Generating the Certificate Request # Create server key echo ""; echo "Creating server key"; echo "" openssl genrsa -des3 -out server$.key.pass -passout pass:1234 $ || exit # Remove passphrase echo ""; echo "Removing passphrase"; echo "" openssl rsa -in server$.key.pass -out server$.key -passin pass:1234 || exit # Generate certificate request echo ""; echo "Generating certificate request"; echo "" openssl req -config $ -new -days 3650 -key server$.key -out csr$.pem || exit # Signing the Certificate echo ""; echo "Signing the Certificate"; echo "" openssl ca -config $ -days 3650 -extensions sign_ias_csr -out new$.pem -in csr$.pem || exit # Generate a Public/Private key file cp server$.key cert$.pem openssl x509 -in new$.pem >> cert$.pem || exit # Generate the PKCS12 file echo ""; echo "Generating PKCS12"; echo "" openssl pkcs12 -name "Test Cert" -export -in cert$.pem -out cert$.p12 || exit 
chmod +x /root/sslCA/gencert.sh /root/sslCA/gencert.sh 01 

При запросе **Common Name (eg, your name or your server’s hostname) []:** нужно обязательно ввести FQDN DC для которого создаем сертификат.

cp /root/sslCA/cacert.pem /etc/pki/tls/certs/ c_rehash rpm -ivh openldap-clients-2.3.43-12.el5.i386.rpm 
# Instruct client to NOT request a server's cert. TLS_REQCERT never # Define location of CA Cert TLS_CACERT /etc/pki/tls/certs/cacert.pem TLS_CACERTDIR /etc/pki/tls/certs 
cp /etc/openldap/ldap.conf /var/www/.ldaprc 
Установка сертификатов на DC

1. Копируем на сервер файлы
* cert.p12 — The certificate
* cacert.pem — The Root Certificate

2 .Start, Run, MMC, File, Add/Remove Snap-in, Add, Certificates, Computer Account, Local Computer, My User Account, Next, Finish, Close, Ok

3. Разворачиваем Certificates

4. Импортируем cacert.pem в Trusted Root Certificates Authorities (правой кнопкой на Trusted Root Certificates Authorities, All Tasks, Import, Next, Browse, All files, выбираем наш cacert.pem . )

5. Импортируем cert.p12 в Personal (правой кнопкой на Personal, All Tasks, Import, Next, Browse, All files, находим наш cert.p12, если нужно вводим пароль . )

6. Проверяем сертифика на DC
* Разворачиваем папки Personal и Certificates
* Двойной щклчок по установленному сертификару
* Убеждаемся, что есть строка «You have a private key that corresponds to this certificate»

Проверка сзязи

Источник

Authenticating in PHP using LDAP through Active Directory

Importing a whole library seems inefficient when all you need is essentially two lines of code.

$ldap = ldap_connect("ldap.example.com"); if ($bind = ldap_bind($ldap, $_POST['username'], $_POST['password'])) < // log them in! >else < // error message >

Some installations of AD will bind successfully if the password provided is empty. Watch out for this! You may need to ensure a non-empty password before trying to authenticate.

@Neal You may be able to use ldap_set_option to make it behave in a different way. Perhaps setting the protocol version? You will have to experiment. I would personally suggest you check for an empty password anyway, just to be safe.

To the anonymous editor: no, to my knowledge, input sanitization isn’t required here as ldap_bind would be handling it and special characters aren’t an issue.

You would think that simply authenticating a user in Active Directory would be a pretty simple process using LDAP in PHP without the need for a library. But there are a lot of things that can complicate it pretty fast:

  • You must validate input. An empty username/password would pass otherwise.
  • You should ensure the username/password is properly encoded when binding.
  • You should be encrypting the connection using TLS.
  • Using separate LDAP servers for redundancy in case one is down.
  • Getting an informative error message if authentication fails.

It’s actually easier in most cases to use a LDAP library supporting the above. I ultimately ended up rolling my own library which handles all the above points: LdapTools (Well, not just for authentication, it can do much more). It can be used like the following:

use LdapTools\Configuration; use LdapTools\DomainConfiguration; use LdapTools\LdapManager; $domain = (new DomainConfiguration('example.com')) ->setUsername('username') # A separate AD service account used by your app ->setPassword('password') ->setServers(['dc1', 'dc2', 'dc3']) ->setUseTls(true); $config = new Configuration($domain); $ldap = new LdapManager($config); if (!$ldap->authenticate($username, $password, $message)) < echo "Error: $message"; >else < // Do something. >

The authenticate call above will:

  • Validate that neither the username or password is empty.
  • Ensure the username/password is properly encoded (UTF-8 by default)
  • Try an alternate LDAP server in case one is down.
  • Encrypt the authentication request using TLS.
  • Provide additional information if it failed (ie. locked/disabled account, etc)

There are other libraries to do this too (Such as Adldap2). However, I felt compelled enough to provide some additional information as the most up-voted answer is actually a security risk to rely on with no input validation done and not using TLS.

Источник

Оцените статью