Home » CakePHP » CakePHP 2.0 Ldap Authentication

With CakePHP 2.0 the authentication system has been completely redesigned to allow for extending the Auth component to allow other methods of authentication and authorization.  I finally sat down last weekend and updated my LDAPAuth component to work with the new version.  While I was doing it I added a few new features that people had been asking for. Also by updating this component I ended up also updating the Ldap Datasource. This included a lot of code cleanup as well.

You can get the new code at https://github.com/analogrithems/idbroker/tree/dev_cake2.0

To get things going download the idbroker code from github and place it in your  plugin folder App/Plugin/Idbroker pay attention to the new capital first letter.  This is a new convention for the CakePHP 2.0 to help in automatic class loading.

Now in your App/Controller/AppController.php you need a minimal of the following

<?php
class AppController extends Controller {
        var $components = array('Auth', 'Session', 'RequestHandler');

        var $user;

        function beforeFilter(){
                global $menus;
                $this->Auth->authenticate = array('Idbroker.Ldap'=>array('userModel'=>'Idbroker.LdapAuth'));
                //If you want to do your authorization from the isAuthorized Controller use the following
                $this->Auth->authorize = array('Controller');
        }


        /*
        * This just says aslong as this is a valid user let them in, you can also modify this to restrict to a group
        */
        public function isAuthorized(){
                $user = $this->Auth->user();
                if($user) return true;
                return false;
        }
}

Notice:That in the components you define the Auth component. This is making all your controllers register the authentication component. In the beforeFilter you are specifically stating you want to use the Idbroker’s Ldap Auth. Then you’re also telling your app to use the prepackaged model for the LDAP component.

The next step is to configure your Users controller and your views.

In your /App/Controller/UsersController.php

<?php
class UsersController extends AppController {
        var $name = 'Users';

        /*
        * Make sure to define which functions don't require auth to be accessed
        */
        function beforeFilter(){
                $this->Auth->allow('usernameExists', 'forgotPassword', 'signup','login','logout');
                parent::beforeFilter();
        }

        function login(){
                if ($this->request->is('post')) {
                        if ($this->Auth->login()) {
                                return $this->redirect($this->Auth->redirect());
                        } else {
                                $this->Session->setFlash(__('Username or password is incorrect'), 'default', array('class'=>'error-message'), 'auth');
                        }
                }
        }

        function logout(){
                $this->log("Destroying session",'debug');
                $this->Session->destroy();
                $this->redirect($this->Auth->logout());
        }
}

You’ll notice compared to previous version of the authcomponent you used to just have the Auth component automatically do the auth, now you actually call $this->Auth->login() to get it to actually check the username and password and run the login logic.

We’re not done yet, we also need to create our view /App/View/Users/login.ctp

<div id='loginForm'>
<?php
        echo $this->Session->flash('auth');
        echo $this->Form->create('Users', array('action' => 'login'));
        echo $this->Form->input('username');
        echo $this->Form->input('password',array('value'=>''));
        echo $this->Form->input('remember',array('type' => 'checkbox', 'label' => 'Remember me'));
        echo $this->Form->submit('Login');
?>
</div>

Last piece to tie this all together is telling your application how to access your LDAP server. Add something like this to youyr /App/Config/database.php

<?php
class DATABASE_CONFIG {
        public $ldap = array (
                        'datasource' => 'Idbroker.LdapSource',
                        'host' => 'localhost',
                        'port' => 389,
                        'basedn' => 'DC=example,DC=com',
                        'login' => 'CN=Manager,DC=example,DC=com',     //For Proxy Userdn
                        'password' => 'LdapPassword',  //For Proxy UserDN password
                        'database' => '',
                        'tls'         => false,
                        'type' => 'OpenLDAP', //Available types are 'OpenLDAP', 'ActiveDirectory', 'Netscape'
                        'version' => 3
        );
}

And in your /App/Config/bootstrap.php add the following to the very bottom

CakePlugin::load('Idbroker');
Configure::load('ldap');

These two lines tell your app to first load the Idbroker plugin and then load the ldap config file which you will create next.

Then create an ldap config file /App/Config/ldap.php with the following. This config file will configure how Ldap is used through out your app.

/**
 * LDAP Settings
 *
 */
        $config['LDAP']['Db']['Config'] = 'ldap'; //What is the name of the db config that has the LDAP credentials
        $config['LDAP']['User']['Identifier'] = 'uid'; //What is the LDAP attribute that identifies the username attribute,
                                                       // openldap, iplant, netscapr use uid, AD uses samaccountname
        $config['LDAP']['Group']['Identifier'] = 'cn'; //What is the LDAP attribute that identifies the group name, usually cn
        $config['LDAP']['Model'] = 'Idbroker.LdapAuth'; //Default model to use for LDAP components
        $config['LDAP']['LdapAuth']['Model'] = 'Idbroker.LdapAuth';
        $config['LDAP']['LdapAuth']['MirrorSQL']['Users'] = 'User'; //A SQL table to duplicate ldap records in for user
        $config['LDAP']['LdapAuth']['MirrorSQL']['Groups'] = 'Group'; //A SQL table to duplicate LDAP records in for groups
        $config['LDAP']['LdapACL']['Model'] = 'Idbroker.LdapAcl';
        $config['LDAP']['LdapACL']['groupType'] = 'group';
        $config['LDAP']['groupType'] = 'groupofuniquenames'; //What object class do you use for your groups?
        $config['LDAP']['Group']['behavior']['tree']['parent_id'] = '49db8df1-5e74-4e91-b15f-4d33e927f14e'; //Are you using a tree behavior?  Need to set the default parent_id?

That last part was a lot, not all of that is needed. Really just the first line is $config[‘LDAP’][‘Db’][‘Config’] = ‘ldap’; – this part tells your application which database config to use for LDAP. The other config options are for new extended features that I will explain below.

When creating this plugin I made use of the new extended features to allow you to use the HTTP basic authentication. In this method you can actually pass your username and password credentials in the http request header. This is useful for allowing command line tools like wget & curl to access authorized parts of your application. It is also used for rest applications.

Another new features that has been added to this Auth Component is the ability to have Ldap Auth mirror a SQL table. What this means is that if you really want to have your user information in SQL but just have authentication come from Ldap you can do that. You need to add the following configuration options to the bootstrap.php These tell it which Models to use to mirror the data to and what the LDAP identifiers are for the data.

        $config['LDAP']['LdapAuth']['MirrorSQL']['Users'] = 'User'; //A SQL table to duplicate ldap records in for user
        $config['LDAP']['LdapAuth']['MirrorSQL']['Groups'] = 'Group'; //A SQL table to duplicate LDAP records in for groups
        $config['LDAP']['User']['Identifier'] = 'uid'; //What is the LDAP attribute that identifies the username attribute,
                                                       // openldap, iplant, netscapr use uid, AD uses samaccountname
        $config['LDAP']['Group']['Identifier'] = 'cn'; //What is the LDAP attribute that identifies the group name, usually cn

Have a question?

Discuss it in the CakePHP 2.0 Ldap Plugin Forum

50 thoughts on “CakePHP 2.0 Ldap Authentication

  1. Brett says:

    Hi,

    This looks exactly what I need for a project however I can’t get it to work… I’ve followed your instructions carefully and placed this plugin in a fresh cakephp install but I get this error:

    Authentication adapter "Ldap" was not found.

    Error: An Internal Error Has Occurred.
    Stack Trace

    #0 C:\wamp\www\catnetv2\lib\Cake\Controller\Component\AuthComponent.php(637): AuthComponent->constructAuthenticate()
    #1 C:\wamp\www\catnetv2\lib\Cake\Controller\Component\AuthComponent.php(514): AuthComponent->identify(Object(CakeRequest), Object(CakeResponse))
    #2 C:\wamp\www\catnetv2\app\Controller\UsersController.php(7): AuthComponent->login()
    #3 [internal function]: UsersController->login()
    #4 C:\wamp\www\catnetv2\lib\Cake\Controller\Controller.php(473): ReflectionMethod->invokeArgs(Object(UsersController), Array)
    #5 C:\wamp\www\catnetv2\lib\Cake\Routing\Dispatcher.php(104): Controller->invokeAction(Object(CakeRequest))
    #6 C:\wamp\www\catnetv2\lib\Cake\Routing\Dispatcher.php(86): Dispatcher->_invoke(Object(UsersController), Object(CakeRequest), Object(CakeResponse))
    #7 C:\wamp\www\catnetv2\app\webroot\index.php(96): Dispatcher->dispatch(Object(CakeRequest), Object(CakeResponse))
    #8 {main}

  2. Brett says:

    LOL… nevermind I must have accidentally downloaded the 1.3 version.

  3. good to hear, if you run into an issue with the 2.0 branch email your current project and I’ll try to debug it for you.

  4. Rodrigo says:

    hello,

    I’m trying to use your code but after do all steps above my app is returning the following errors:

    “Error: Database table app_models for model AppModel was not found.”

    #0 /var/www/html/artigos/lib/Cake/Model/Model.php(3236): Model->setSource(‘app_models’)
    #1 /var/www/html/artigos/lib/Cake/Model/Model.php(2458): Model->getDataSource()
    #2 /var/www/html/artigos/app/Plugin/Idbroker/Controller/Component/Auth/LdapAuthenticate.php(135): Model->find(‘first’, Array)
    #3 /var/www/html/artigos/app/Plugin/Idbroker/Controller/Component/Auth/LdapAuthenticate.php(70): LdapAuthenticate->_getDn(‘id’, ‘rodrigo’)
    #4 /var/www/html/artigos/lib/Cake/Controller/Component/AuthComponent.php(635): LdapAuthenticate->authenticate(Object(CakeRequest), Object(CakeResponse))
    #5 /var/www/html/artigos/lib/Cake/Controller/Component/AuthComponent.php(509): AuthComponent->identify(Object(CakeRequest), Object(CakeResponse))
    #6 /var/www/html/artigos/app/Controller/UsersController.php(7): AuthComponent->login()
    #7 [internal function]: UsersController->login()
    #8 /var/www/html/artigos/lib/Cake/Controller/Controller.php(473): ReflectionMethod->invokeArgs(Object(UsersController), Array)
    #9 /var/www/html/artigos/lib/Cake/Routing/Dispatcher.php(107): Controller->invokeAction(Object(CakeRequest))
    #10 /var/www/html/artigos/lib/Cake/Routing/Dispatcher.php(89): Dispatcher->_invoke(Object(UsersController), Object(CakeRequest), Object(CakeResponse))
    #11 /var/www/html/artigos/app/webroot/index.php(96): Dispatcher->dispatch(Object(CakeRequest), Object(CakeResponse))
    #12 {main}

    Do you know what i did wrong?

    Thank you!

    • update from github and the issue should be resolved. Also see the changes in the post above, I added more information to help out with the authorization since you may not be using a user table and need to authorize actions

  5. Quentin says:

    Hi,

    Your code is very useful for me, and for a lot of people I think, please keep doing such an amazing job !

    However, I’m running into an issue (I experimented the two issues above also …).
    It’s about “datasource missing config”.

    My app is returning the following errors :

    Error: The datasource configuration was not found in database.php.

    #0 C:\inetpub\wwwroot\tds\lib\Cake\Model\ConnectionManager.php(91): ConnectionManager::_getConnectionObject(NULL)
    #1 C:\inetpub\wwwroot\tds\app\Plugin\Idbroker\Model\IdbrokerAppModel.php(9): ConnectionManager::getDataSource(NULL)
    #2 C:\inetpub\wwwroot\tds\app\Plugin\Idbroker\Model\LdapAuth.php(13): IdbrokerAppModel->__construct()
    #3 C:\inetpub\wwwroot\tds\lib\Cake\Utility\ClassRegistry.php(136): LdapAuth->__construct(Array)
    #4 C:\inetpub\wwwroot\tds\app\Plugin\Idbroker\Controller\Component\Auth\LdapAuthenticate.php(50): ClassRegistry::init(‘Idbroker.LdapAu…’)
    #5 C:\inetpub\wwwroot\tds\lib\Cake\Controller\Component\AuthComponent.php(677): LdapAuthenticate->__construct(Object(ComponentCollection), Array)
    #6 C:\inetpub\wwwroot\tds\lib\Cake\Controller\Component\AuthComponent.php(638): AuthComponent->constructAuthenticate()
    #7 C:\inetpub\wwwroot\tds\lib\Cake\Controller\Component\AuthComponent.php(515): AuthComponent->identify(Object(CakeRequest), Object(CakeResponse))
    #8 C:\inetpub\wwwroot\tds\app\Controller\UsersController.php(15): AuthComponent->login()
    #9 [internal function]: UsersController->login()

    My config in database.php :

    public $ldap = array (
    ‘datasource’ => ‘Idbroker.LdapSource’,
    ‘host’ => ‘192.168.56.2’,
    ‘port’ => 389,
    ‘basedn’ => ‘CN=Users,DC=test,DC=com’,
    ‘login’ => ‘CN=Administrateur,CN=Users,DC=test,DC=com’, //For Proxy Userdn
    ‘password’ => ‘xxxxx’, //For Proxy UserDN password
    ‘database’ => ”,
    ‘tls’ => false,
    ‘type’ => ‘ActiveDirectory’, //Available types are ‘OpenLDAP’, ‘ActiveDirectory’, ‘Netscape’
    ‘version’ => 3
    );

    Do you have any idea where this comes from ?
    In the same time, I send you the entire project by email.

    Thank you !
    Quentin

  6. Brett says:

    Tried again with updated code and instructions above and just get this:
    Missing Datasource Configuration

    Error: The datasource configuration was not found in database.php.

    Notice: If you want to customize this error message, create app\View\Errors\missing_datasource_config.ctp
    Stack Trace

    #0 C:\wamp\www\catnetv2\lib\Cake\Model\ConnectionManager.php(94): ConnectionManager::_getConnectionObject(NULL)
    #1 C:\wamp\www\catnetv2\app\Plugin\Idbroker\Model\IdbrokerAppModel.php(9): ConnectionManager::getDataSource(NULL)
    #2 C:\wamp\www\catnetv2\app\Plugin\Idbroker\Model\LdapAuth.php(13): IdbrokerAppModel->__construct()
    #3 [internal function]: LdapAuth->__construct(Array)
    #4 C:\wamp\www\catnetv2\lib\Cake\Utility\ClassRegistry.php(141): ReflectionClass->newInstance(Array)
    #5 C:\wamp\www\catnetv2\app\Plugin\Idbroker\Controller\Component\Auth\LdapAuthenticate.php(50): ClassRegistry::init(‘Idbroker.LdapAu…’)
    #6 C:\wamp\www\catnetv2\lib\Cake\Controller\Component\AuthComponent.php(676): LdapAuthenticate->__construct(Object(ComponentCollection), Array)
    #7 C:\wamp\www\catnetv2\lib\Cake\Controller\Component\AuthComponent.php(590): AuthComponent->constructAuthenticate()
    #8 C:\wamp\www\catnetv2\lib\Cake\Controller\Component\AuthComponent.php(314): AuthComponent->_getUser()
    #9 [internal function]: AuthComponent->startup(Object(PagesController))
    #10 C:\wamp\www\catnetv2\lib\Cake\Utility\ObjectCollection.php(104): call_user_func_array(Array, Array)
    #11 C:\wamp\www\catnetv2\lib\Cake\Controller\Controller.php(606): ObjectCollection->trigger(‘startup’, Array)
    #12 C:\wamp\www\catnetv2\lib\Cake\Routing\Dispatcher.php(101): Controller->startupProcess()
    #13 C:\wamp\www\catnetv2\lib\Cake\Routing\Dispatcher.php(86): Dispatcher->_invoke(Object(PagesController), Object(CakeRequest), Object(CakeResponse))
    #14 C:\wamp\www\catnetv2\app\webroot\index.php(96): Dispatcher->dispatch(Object(CakeRequest), Object(CakeResponse))
    #15 {main}

    In my database.php file I have this:
    public $ldap = array (
    ‘datasource’ => ‘Idbroker.LdapSource’,
    ‘host’ => ‘server’,
    ‘port’ => 389,
    ‘basedn’ => ‘DC=domain,DC=local’,
    ‘login’ => ‘user’,
    ‘password’ => ‘pass’,
    ‘database’ => ”,
    ‘tls’ => false,
    ‘type’ => ‘ActiveDirectory’, //Available types are ‘OpenLDAP’, ‘ActiveDirectory’, ‘Netscape’
    ‘version’ => 3
    );

    Any ideas?

  7. Quentin says:

    Hi Brett,

    Try to copy the LDAP settings from bootstrap.php to ldap.php for example and load it in the bootstrap :

    //app/Config/bootstrap.php
    Configure::load(‘ldap’);
    CakePlugin::loadAll();

    and

    //app/Config/ldap.php
    <?php
    $config['LDAP']['Db']['Config'] = 'ldap';
    $config['LDAP']['User']['Identifier'] = 'samaccountname';

    It worked for me.

    But I have still some issues with the _getDn function of LdapAuthenticate.
    The function doesn't return a value for $dn.

    Quentin

    • did your debug show the query? It should be the first line and look something like

      search | scope: sub | cond: uid=analogrithems | targetDn: DC=analogrithems,DC=net | order: | limit: 1

      • Quentin says:

        It was a little mistake in my config … 😉

        I have no more issue, except one :
        First step) I’m logging in with invalid credentials.
        Reaction : $this->Auth->login() returns false.

        Second step) I’m logging in with valid credentials.
        Reaction : $this->Auth->login() returns true.

        Third step) I’m logging out then I try with invalid credentials.
        Reaction : $this->Auth->login() returns true !

        I see with wireshark that, in the third step, LDAP messages contain credentials of second step…
        Rebooting my browser resets the problem (really weird…).

        Any ideas ?

        Also, I don’t know how to use the debug to show queries you talked about.

        • Quentin says:

          I solved my problem by removing :

          $this->Session->destroy();
          before
          $this->redirect($this->Auth->logout());

          I think Auth->logout() needs the session to work properly.
          I will try your new features today… I keep you informed.

          Thank you !

  8. Quentin says:

    Hi !

    I come back with a new issue and a little correction.

    First, the correction : in LdapAuthenticate.php, function existsOrCreateSQLUser, it should be :

    if(isset($result) && !empty($result)){
    instead of
    if(isset($result)){

    Yes… it was almost nothing 😉
    Your SQLMirroring feature is very useful for me, thanks again !

    Then, an issue I try to debug since yesterday :
    -> I’m logging in with valid credentials.
    Reaction : login is successfull and user informations are stored in the session variable (ldap/user mixed, normal ?)
    -> I’m going to another page or refresh.
    Reaction : session is lost, I’m not logged in anymore …

    It’s very frustrating because it could be caused by a lot of things, but do you have any idea about that ?

    • It sounds like you may have accidentally placed that session->destroy somewhere else, or you have a redirect directing you at logout.

    • Brett says:

      Think I’m having a similar problem but nothing seems to go into the session in the first place (except for username or password), ldap lookup seems to go ok finds the user then plonks me back on the login page (LoggedInUser is empty).

      • are you doing sqlMirroring? If so what does your user schema look like?

        • Brett says:

          No not using mirroring at this point.

          • Heidi says:

            Sorry that I missed the two warnings that that followed the three notices mentioned in my earlier post. So all together there are three notices (as in Brett’s case) and two warnings. I also found that when the login credentials are right, the username is inserted into the users table.

            Warning (2): Cannot modify header information – headers already sent by (output started at C:\…\cake\lib\Cake\Utility\Debugger.php:744) [CORE\Cake\Model\Datasource\CakeSession.php, line 666]

            Warning (2): session_regenerate_id() [function.session-regenerate-id]: Cannot regenerate session id – headers already sent [CORE\Cake\Model\Datasource\CakeSession.php, line 668]

        • Brett says:

          Also tried with sql mirroring, seems to add user/group ok to db. Doesn’t leave me logged in though and get these errors at top:

          Notice (8): Undefined property: LdapAuthenticate::$sqlModel [APP\Plugin\Idbroker\Controller\Component\Auth\LdapAuthenticate.php, line 219]

          Notice (8): Trying to get property of non-object [APP\Plugin\Idbroker\Controller\Component\Auth\LdapAuthenticate.php, line 219]

          Notice (8): Undefined index: [APP\Plugin\Idbroker\Controller\Component\Auth\LdapAuthenticate.php, line 219]

          Users table just looks like:
          `id` int(11) NOT NULL AUTO_INCREMENT,
          `username` varchar(255) NOT NULL,
          `group_id` int(11) NOT NULL,
          `created` datetime DEFAULT NULL,
          `modified` datetime DEFAULT NULL,
          PRIMARY KEY (`id`),
          UNIQUE KEY `username` (`username`)

          Is anything else required for it to work?

          Thanks,

          -Brett

          • email me your project and I’ll see if it happens on my server.

          • Heidi says:

            I encountered exactly the same errors as Brett did (the post on January 18, 2012 at 7:41 pm). Is there any solution available? Thanks a lot in advance.

            My user table is like this:
            CREATE TABLE `users` (
            `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
            `name` varchar(100) DEFAULT NULL,
            `email` varchar(150) DEFAULT NULL,
            `firstname` varchar(60) DEFAULT NULL,
            `lastname` varchar(60) DEFAULT NULL,
            `username` varchar(100) NOT NULL,
            `created` datetime DEFAULT NULL,
            `modified` datetime DEFAULT NULL,
            PRIMARY KEY (`id`)
            )

            Heidi

          • Here is the schema I was using

            CREATE TABLE IF NOT EXISTS `users` (
            `id` char(36) COLLATE utf8_unicode_ci NOT NULL,
            `firstname` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
            `lastname` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
            `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
            `password` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
            `displayname` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
            `email` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
            `dn` varchar(256) COLLATE utf8_unicode_ci DEFAULT NULL,
            PRIMARY KEY (`id`),
            UNIQUE KEY `username` (`username`),
            UNIQUE KEY `email` (`email`),
            UNIQUE KEY `dn` (`dn`)
            ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

            In the auth component the function existsOrCreateSQLUser($user) is currently designed for use against openldap. A little modification may be needed to make it work with active directory. Look around line 211 you’ll need to define the ldap attributes you want to map to your sql table. In the future I’ll find a cleaner to map them.

          • Heidi says:

            Hi

            Thanks so much for your reply.

            I recreated the table according to your post (February 21, 2012 at 11:08 pm) and did what benef said (February 16, 2012 at 9:16 am) by changing line 219 to $this->sqlUserModel. I tried to login again and the fields (username, displayname, email, dn) were populated.

            I still wasn’t able to login though and the log (ldap.error.log) was printed “Ldap.error: Failed to update sql mirrored groups:”.

            It turned out that when the method existsOrCreateSQLGroup was called around line 116, the second argument $groups was FALSE as returned by getGroups.

            So I looked into getGroups and found that the model wasn’t able to find, based on the conditions (‘objectclass’=>’groupofuniquenames’, ‘uniquemember’=>$user[‘dn’])) what it was supposed to find on line 233 to 234.

            Is there any way to solve this problem?

            I’ve to say this plugin is awesome, especially on the part of sqlmirroring. I really hope we could find the solution so that it works for Active Directory.

            Heidi

  9. Brett says:

    Just a tip if you’re getting “LDAP not configured on this server.”… make sure you have the ldap php module loaded! 😀

  10. Andreas says:

    I just dl your plugin, put it in an new installation of cakephp 2 and now I always get this error:

    Authentication adapter "Ldap" was not found.
    Error: An Internal Error Has Occurred.

    Stack Trace

    #0 /Users/awidmer/Dropbox/Projects/excelsis/lib/Cake/Controller/Component/AuthComponent.php(637): AuthComponent->constructAuthenticate()
    #1 /Users/awidmer/Dropbox/Projects/excelsis/lib/Cake/Controller/Component/AuthComponent.php(514): AuthComponent->identify(Object(CakeRequest), Object(CakeResponse))
    #2 /Users/awidmer/Dropbox/Projects/excelsis/app/Controller/UsersController.php(15): AuthComponent->login()
    #3 [internal function]: UsersController->login()
    #4 /Users/awidmer/Dropbox/Projects/excelsis/lib/Cake/Controller/Controller.php(473): ReflectionMethod->invokeArgs(Object(UsersController), Array)
    #5 /Users/awidmer/Dropbox/Projects/excelsis/lib/Cake/Routing/Dispatcher.php(104): Controller->invokeAction(Object(CakeRequest))
    #6 /Users/awidmer/Dropbox/Projects/excelsis/lib/Cake/Routing/Dispatcher.php(86): Dispatcher->_invoke(Object(UsersController), Object(CakeRequest), Object(CakeResponse))
    #7 /Users/awidmer/Dropbox/Projects/excelsis/app/webroot/index.php(96): Dispatcher->dispatch(Object(CakeRequest), Object(CakeResponse))
    #8 {main}

  11. Saito says:

    Hi,
    Your plugin and tutorial are both great!
    However, i noticed some things that didn’t figured in the tutorials for Active Directory users.
    I’m very new to cakephp and don’t know any of the tricks except the blog tutorial. 🙁
    I’m using Active Directory, and i had a lot of issues for some configuration.

    – in the database.php, for active directory configuration the login is :
    ‘basedn’ => ‘OU=ExampleOU,DC=example,DC=com’,
    ‘login’ => ‘yourLogin@example.com’,
    ‘password’ => ‘yourLdapPassword’

    – the line $this->Auth->authenticate = array('Idbroker.Ldap'=>array('userModel'=>'Idbroker.LdapAuth')); in AppController.php
    always returned false on login as i was using my own user model, so i changed it for
    $this->Auth->authenticate = array('Idbroker.Ldap'=>array('userModel'=>'User'));

    – i noticed that the mirror sql mode returns an error when creating the user, the user is created, but the redirection does not occur.
    When the user already exists in the database, there are no errors. What is the appropriate user table structure?
    From now on i just commented the mirror sql options and left the others but the whole rest works.

    • email me a copy of your project and I’ll take a look analogrithems at gmail

      • Saito says:

        FIXED! see details below.

        analogrithems says: [February 21, 2012 at 11:08 pm ]
        In the auth component the function existsOrCreateSQLUser($user) is currently designed for use against openldap. A little modification may be needed to make it work with active directory. Look around line 211 you’ll need to define the ldap attributes you want to map to your sql table. In the future I’ll find a cleaner to map them.

        All the ldap attributes seems to be correct, owing to the ldap.error.log. I checked it and saw that all attributes used by the array were returned by my Active Directory.
        However, benef’s solution seems to work as you use $this->sqlUserModel in the whole function and return $this->sqlModel in LdapAuthenticate.php. And that’s what generates the cake php error of undefined attribute for me.

        benef says: [February 16, 2012 at 9:16 am ]
        Hi, I suggest you to change return $result[$this->sqlModel->alias]; by return $result[$this->sqlUserModel->alias];.
        By the way, thank you very much, this helps me very much, if i find other things like that i’ll tell you.

        By correcting the line 219 of LdapAuthenticate.php as benef said, it fixed my sql mirroring issue. By now all is correct and works perfectly even with a user table having only :
        users(id, username, password, role, created, modified)

        Thanks for everything this plugin is really great! 😉

  12. benef says:

    Hi, I suggest you to change return $result[$this->sqlModel->alias]; by return $result[$this->sqlUserModel->alias];.
    By the way, thank you very much, this helps me very much, if i find other things like that i’ll tell you.

    • Brett says:

      I finally got around to playing with this more and yeah I also needed return $result[$this->sqlUserModel->alias]; in LdapAuthenticate.php for use on AD.

      Also, for some reason the $user array in LdapAuthenticate.php was returning null values for me so none of my custom fields were getting saved in the user table. Turns out all the user data was in a sub array called LdapAuth.

      So I had to change (for example):
      if(isset($user['mail']) && !empty($user['mail']) ) $u['email'] = $user['mail'];
      to:
      if(isset($user['LdapAuth']['mail']) && !empty($user['LdapAuth']['mail']) ) $u['email'] = $user['LdapAuth']['mail'];

      Hopefully that helps somebody with the same issues.

  13. Ravi says:

    Hi,
    Thanks for the blog post. It has come very handy in connecting to our ldap database. Especially the SQL Mirroring.

    I was able to setup most of it but the line 14 of the UsersController.php that checks whether the request is a ‘post’ was not working. The form does ‘post’ the information to the system but the variable is missing from the request params. Am I missing something? When I comment out that ‘if’ statement, it was going tot he next stage.

    thanks
    Ravi

  14. propiuita says:

    Hi,

    it seams a really nice plugin…
    is there also possible to authenticate with a separate model nearby ldap

    case:
    try ldapUser auth
    catch appUser auth
    exept no login

    Authentication -> Model:
    ldapUser -> User
    appUser -> appUser

    hope you understand what i mean 😉

    best

  15. Heidi says:

    I’ve done everything suggested here already but I’m still returned to the login page with the header “You are not authorized to access that location.” I wonder if I’m missing something basic about Cakephp here.

    The login and SQL mirroring were in fact successful. I even use the following line n UsersController.php and I was returned a TRUE value.

    debug($this->Auth->login());

    I’ve been working on the problem for days now and I’ll be grateful if you can solve my problem.

    Thanks a lot.

    • Saito says:

      Have you tried changing the line

      $this->Auth->authenticate = array('Idbroker.Ldap'=>array('userModel'=>'Idbroker.LdapAuth'));

      in your AppController.php by the following

      $this->Auth->authenticate = array('Idbroker.Ldap'=>array('userModel'=>'User'));

      I had the same issue and it took me 2 weeks to find this. I was always prompted that i wasn’t authorised to access the location, except by adding the given location to the auth allow array. Then I changed the userModel param, by the user model (User in the tutorial) I was using and it worked.

  16. Saito says:

    Oh i thought there was a user model in the tutorial. My bad, sorry!
    However if you are using your own user model, you can add these lines in its declaration in addition to what i said before.

    var $useDbConfig = ‘ldap’;//to tell the model which dbconfig to use
    var $primaryKey = ‘samaccountname’;//if you use Active Directory
    var $useTable = ”; // Needed for LDAP datasource

    I noticed that when i try to use the LdapAuth model, even with my config, it still returns me false while logging in.

    • Heidi says:

      No luck, Saito. I just tried your suggestion and this time I was redirected to the login page (like last time) and given the line “Username or password is incorrect”. But I’ve been mulling over the need of the user model because the primary key samaccountname can be specified in ldap.php.

      In fact I’m considering lines 15 and 16 of UserController.php. I used debug() to examine the return value of $this->Auth->login() Line 15 and 1 was returned, it means that the login was successful. But once the next line (return $this->redirect($this->Auth->redirect());) was executed, I was redirected to the login page with the message “You are not authorized to access that location”.

      Like you, I’ve been working on this component for over two weeks now and still hasn’t got a clue to solve the problem.

      • Saito says:

        Hi again Heidi,
        I don’t know if it is a good solution but, I was wondering why did my authentication worked with my own user model and not with Idbroker.LdapAuth’s.
        And I noticed one detail while reading the whole code : the LdapAuth model was extending IdbrokerAppModel.
        Then I went to the /app/Plugin/Idbroker/Model/LdapAuth.php and changed the line 2 :
        class LdapAuth extends IdbrokerAppModel {
        by the line
        class LdapAuth extends AppModel {
        and it worked. I didn’t find any error in the IdbrokerAppModel but maybe the if(isset(…)) condition causes the “you’re not authorized to access this location” error.
        Try to do it, I hope it will fix your authorization issue!

  17. Heidi says:

    I followed Saito’s posts on [March 2, 2012 at 6:27 am] and [March 16, 2012 at 6:38 am] and now I can login successfully but SQL mirroring isn’t possible.

  18. Heidi says:

    Finally everything’s working fine now! I followed Saito post on [March 16, 2012 at 6:38 am] but revert the change mentioned in the post on [March 2, 2012 at 6:27 am] to the original line:

    $this->Auth->authenticate = array('Idbroker.Ldap'=>array('userModel'=>'Idbroker.LdapAuth'));

    Now not only login is successful but SQL mirroring’s working beautifully.

    Thanks a lot, Saito! And got to thank analogrithems for the plugin too!

  19. Calvin says:

    I have a really basic/dumb question. What file/s should I download and copy to App/Plugin/Idbroker folder?

  20. Brett says:

    Has anybody been able to get any of the remember me/auto-login plugins components working with LdapAuth? I’ve tried:
    http://milesj.me/code/cakephp/auto-login
    and
    https://github.com/voidet/remember_me

    But can’t get either working with much hacking around.

    Alternatively does anybody have their own code snippet they can share?

    Cheers.

  21. Glen says:

    I have a question if someone can assist, for this block of code:

    $config[‘LDAP’][‘Db’][‘Config’] = ‘ldap’; //What is the name of the db config that has the LDAP credentials

    I do not know this information, I can use jxplorer to access my ldap server and view my different groups and user id’s etc but I dont know where to get this info from, the problem I am running into is that whenever i enter the correct username and password it tells me it is invalid and that is because I believe I dont have the correct information here. If anyone could help that would be great, thanks.

  22. calvin says:

    Hello,

    Thank you very much for all the plug-in and all the efforts to make this work better. I was wondering if anyone can share a schema for group. Thank you again!

  23. jeremy says:

    I’m using the Idbroker plugin to authenticate against Active Directory and I receive the following error when I attempt to login:

    2012-05-16 13:34:44 Ldap.error: Query Params Failed:
    Array
    (
    [conditions] => (&(objectclass=group)(member=CN=UserID,OU=Users,OU=Staff,OU=IT,DC=domain,DC=org))
    [fields] => Array
    (
    [0] => *
    [1] =>
    [2] => +
    [3] =>
    )

    [joins] => Array
    (
    )

    [limit] =>
    [offset] =>
    [order] => Array
    (
    [0] =>
    )

    [page] => 1
    [group] =>
    [callbacks] => 1
    [scope] => sub
    [type] => search
    [targetDn] => DC=domain,DC=org
    )
    Error: Operations error

    I have tested the query using ldapsearch and it comes back with a listing of the groups I’m a member of. I’ve also captured the search using wireshark and see it query and return a list of groups.

    Any ideas?

  24. Sam says:

    Hey, I love your plugin, thank you for creating this! I did run into one issue when setting it up to communicate with our eDirectory database that I wanted to share in case anyone else has similar issues.

    When attempting to fetch the groups for my user, I was getting the following:

    Warning (2): Illegal offset type [APP/Plugin/Idbroker/Controller/Component/Auth/LdapAuthenticate.php, line 247]

    After some debugging I discovered that $group[$this->model->alias][$groupIdentifer] was returning an array of groups that itself contained an array. This is almost certainly an edge case but the culprit was that one of our groups actually has two cn’s in our eDirectory.

    I fixed it by changing around line 247 from:

    foreach($groups as $group){
    $gid = $group[$this->model->alias][$groupIdentifer];
    }

    to

    foreach($groups as $group){
    if(!is_array($group[$this->model->alias][$groupIdentifer])) {
    $gid = $group[$this->model->alias][$groupIdentifer];
    } else {
    foreach($group[$this->model->alias][$groupIdentifer] as $subgroup) {
    $gid = $subgroup;
    }
    }
    }

    I hope this helps anyone else having this issue. Thank you again!

    Sam

  25. ADM says:

    Thank you! I got this 50% working.. I can login with Active Directory, but have no idea how the ACL would work.

    Does ACL work?

    Does anyone have the SQL table structure of their users, Groups, and ACL Tables?

  26. Dave says:

    Can this support LDAPS?

  27. Dave says:

    IS there a particular way to download a working release for 2.0, the latest does not work. ldapauthenticate.php uses primary key of ‘id’ to match to ‘username’ etc

Leave a Reply

Your email address will not be published. Required fields are marked *

</Random> is Stephen Fry proof thanks to caching by WP Super Cache