Yii 1.1: How to use ldap in UserIdentity for authentication

18 followers

Yii does not have an LDAP class itself, but its very easy to implement LDAP in the stock UserIdentity class.

To do so, open your protected/components/UserIdentity.php and remove or comment out the code in the authenticate() method, before replacing it with this:

$options = Yii::app()->params['ldap'];
$dc_string = "dc=" . implode(",dc=",$options['dc']);
 
$connection = ldap_connect($options['host']);
ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($connection, LDAP_OPT_REFERRALS, 0);
 
if($connection)
{
    // Note: in general it is bad to hide errors, however we're checking for an error below
    $bind = @ldap_bind($connection, "uid={$this->username},ou={$options['ou']},{$dc_string}", $this->password);
 
    if(!$bind) $this->errorCode = self::ERROR_PASSWORD_INVALID;
    else $this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;

Once you have done this, open up your configs/main.php file, and add the following to the 'params' array at the bottom of the file:

'ldap' => array(
    'host' => 'hostname',
    'ou' => 'organisational-unit', // such as "people" or "users"
    'dc' => array('example','com'),
),

Replace the host with the hostname of the LDAP server, ou with the organisational unit you want to authenticate against (most LDAP servers use a broad terminology, such as "people"), and dc with the base DN. (For example array("ucla","edu") // ucla.edu)

Total 15 comments

#17314 report it
Kevork at 2014/05/21 10:19pm
Question about authorization manager after successfully authenticating (with LDAP)

Hi, firstly thank you for this tutorial. My question is about authorization. If I want to have a few different levels based on the group membership of the users (who successfully login - authentication with LDAP as per your tutorial), what steps should I follow? I'm using gii and giix to generate my CRUD forms and then making changes to fit my requirements. Thank you

#16464 report it
Trejder at 2014/02/26 08:19am
Two-step login

Note, that there are systems and LDAP configurations, which requires two-step login approach, in which you don't construct your own DN!

First, you bind anonymously, by specifying only $bind = @ldap_bind($connection);, then you search for a given username (using ldap_search). This search will return you a valid user's DN (or NULL, if particular user does not exist).

Second, using returned LDAP you issue another ldap_bind, this time attempting to actually login user.

#15686 report it
Navarr at 2013/12/06 08:53pm
@Finzaiko

You need to silence the ldap_bind error by prefixing it with a @. I've amended the article to reflect that.

Note: in general this is a bad thing to do, but in this case it may be necessary. Ldap should really be re-worked into some sort of an object resource that throws exceptions instead of errors.

#15685 report it
Finzaiko at 2013/12/06 08:21pm
Error validation

It's work for me if I login right username and password, but if login wrong password i got an error :

ldap_bind() [<a href='function.ldap-bind'>function.ldap-bind</a>]: Unable to bind to server: Invalid credentials

how to return/redirect login form to validate username and password?

#15424 report it
bmadeiro at 2013/11/08 07:36am
Active Directory

@Ace D.

This worked to me!!

$bind = @ldap_bind($connection, $this->username."@".$options['domain'], $this->password);

#13077 report it
d^_^b at 2013/05/02 08:32am
adLDAP

i am trying to use adLDAP but i am having errors, can you provide more information about how to use it

#12895 report it
Ace D. at 2013/04/18 03:29pm
Active Directory

If you use active directory then:

In UserIdentity.php

public function authenticate()
{
        $options = Yii::app()->params['ldap'];
        $connection = ldap_connect($options['host'], $options['port']);
        ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);
        ldap_set_option($connection, LDAP_OPT_REFERRALS, 0);
 
        if($connection)
        {
            try
            {
                @$bind = ldap_bind($connection, $options['domain']."\\".$this->username, $this->password);
            }
            catch (Exception $e){
                echo $e->getMessage();
            }
            if(!$bind) $this->errorCode = self::ERROR_PASSWORD_INVALID;
            else $this->errorCode = self::ERROR_NONE;
        }
        return !$this->errorCode;
}

main.php

'params'=>array(
'ldap'      => array(
                    'host'      => 'serverAd.example.com',
                    'port'      => 389,
                    'domain'    => 'MYDOMAIN',
),
#10456 report it
desh at 2012/10/29 02:40pm
@Navarr

help... I generated the following error: ldap_bind() [function.ldap-bind]: Unable to bind to server: Invalid credentials

#10454 report it
desh at 2012/10/29 02:13pm
@Navarr

Should uncomment the following line: Before Code ;extension = php_ldap.dll

Rate Code: extension = php_ldap.dll

only, or should I see other extensions that I have to move?

#10452 report it
desh at 2012/10/29 01:46pm
@Navarr

thanks for your reply, as I php_ldap.dll or php_ldap.so? where I can get in that directory and go?

#10450 report it
desh at 2012/10/29 01:38pm
ldap_connect error ()

I generated the following error: Fatal error: Call to undefined function ldap_connect() that extention library or should I include? urgent help please! = D fact identical to the example code

#7218 report it
WebDevPT at 2012/03/05 11:30am
Thank you very much

I was just looking for this and this worked like a charm!

Thank you.

#2158 report it
Marcos Mezo at 2010/11/19 11:30am
Why not use php ldap internal functions instead of zend's?

If it is just for validation you can aswell use the native LDAP functions of php without having to download/extract classes from another framework (and without exposing the admin passwd of the ldap server).

I have something along the line of the following (wrapped conveniently on a try/catch block in case the ldap connection cannot be established) working for about 1 year with no problem:

$ds=ldap_connect($serverURL);
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0); 
if ($ds) {
   $r=ldap_bind($ds,"uid=$this->username,ou=Users,dc=example,dc=com",$this->password);
   if (!$r) {
      $this->errorCode=self::ERROR_PASSWORD_INVALID;
   } else {
      $this->errorCode=self::ERROR_NONE;
   }
}
return !$this->errorCode;
#82 report it
Iqbal Syamsu at 2010/09/21 02:25am
okay

yes it's works. fyi, ldap server configuration may vary, i use uid instead of cn.

$ldap->bind("uid=".$this->username.",ou=People,dc=blahblah,dc=com", $this->password);

thanks!

#212 report it
csdaraujo at 2010/08/06 06:35pm
adLDAP

You guys should take a look at this: http://adldap.sourceforge.net/

I've done the same thing with 6 lines of code. Couldn't be simpler! :)

Leave a comment

Please to leave your comment.

Write new article