Jim Yost Posted February 17, 2012 Share Posted February 17, 2012 Howdy! Just created a module for authenticating via LDAP. It works great for our implementation of LDAP, however I'm sure it may need additional work. Looking for some feedback if there are better ways to implement this or clean up my code a bit. File attached. -Jim 1 Link to comment Share on other sites More sharing options...
Jim Yost Posted February 17, 2012 Author Share Posted February 17, 2012 <?php class LdapAuth extends WireData implements Module, ConfigurableModule { public static function getModuleInfo() { return array( "title" => "LDAP Authentication", "version" => 100, "summary" => "Allows uses to be authenticated via LDAP", "permanent" => false, "singular" => true, "autoload" => true ); } public function init() { $this->session->addHookAfter('login', $this, 'login'); } public function ___login($event) { if ($event->return) return; // they are already in $name = $event->arguments[0]; $pass = $event->arguments[1]; $conn = ldap_connect($this->data['host']); if ($conn) { $bind = @ldap_bind($conn, "$name@{$this->data['accountDomainName']}", $pass); if ($bind) { // success // check if they area lready a user in PW $user = wire('users')->get("name=$name"); if (!$user instanceof NullPage) { // update login info $user->pass = $pass; $user->save(); $user = wire('session')->login($name, $pass); $event->return = $user; return; } else { // create a new user $guest = wire('users')->getGuestUser(); $user = new User(); $user->parent = $guest->parent; $user->name = $name; $user->pass = $pass; $user->addRole("guest"); $user->save(); $user = wire('session')->login($name, $pass); $event->return = $user; return; } } else { // fail $event->return = null; return; } } else { // could not connect throw new Exception("Could not connect to LDAP"); } } static public function getModuleConfigInputfields(array $data) { $inputfields = new InputfieldWrapper(); $field = Wire::getFuel('modules')->get('InputfieldText'); $field->attr('name', 'host'); $field->label = 'Host'; if (isset($data['host'])) $field->attr('value', $data['host']); $field->description = 'The LDAP server hostname'; $inputfields->append($field); $field = Wire::getFuel('modules')->get('InputfieldText'); $field->attr('name', 'accountDomainName'); $field->label = 'Account Domain Name'; if (isset($data['accountDomainName'])) $field->attr('value', $data['accountDomainName']); $field->description = 'The LDAP server domain'; $inputfields->append($field); $field = Wire::getFuel('modules')->get('InputfieldText'); $field->attr('name', 'accountDomainNameShort'); $field->label = 'LDAP server domain (short)'; if (isset($data['accountDomainNameShort'])) $field->attr('value', $data['accountDomainNameShort']); $field->description = 'The LDAP server hostname'; $inputfields->append($field); $field = Wire::getFuel('modules')->get('InputfieldText'); $field->attr('name', 'baseDn'); $field->label = 'Base DN'; if (isset($data['baseDn'])) $field->attr('value', $data['baseDn']); $field->description = 'The LDAP server DN'; $inputfields->append($field); $field = Wire::getFuel('modules')->get('InputfieldCheckbox'); $field->attr('name', 'startTls'); $field->label = 'Use TLS'; $field->attr('value', 1); if (isset($data['startTls'])) { if ($data['startTls']) $field->attr('checked', true); } $field->description = 'Check this option to enable TLS security'; $inputfields->append($field); return $inputfields; } } 2 Link to comment Share on other sites More sharing options...
apeisa Posted February 17, 2012 Share Posted February 17, 2012 Great stuff! I know that in our company we will need this for sure, so big thanks from here. I have never implemented ldap myself, so cannot comment much. Only suggestion is to rename your class to SessionLdapAuth so it would go into session category on modules list. Link to comment Share on other sites More sharing options...
WillyC Posted February 17, 2012 Share Posted February 17, 2012 public function ___login($event) { لهذا public function login($event) لا يوجد سبب ليكون آخر هوك هنا تغيير if (!$user instanceof NullPage) { // update login info $user->pass = $pass; $user->save(); لهذا if($user->id) { $user->pass = $pass; if($user->isChanged('pass')) $user->save(); تعديل هذا $guest = wire('users')->getGuestUser(); $user = new User(); $user->parent = $guest->parent; $user->name = $name; $user->pass = $pass; $user->addRole("guest"); $user->save(); $user = wire('session')->login($name, $pass); لهذا $user = wire('users')->add($name); $user->pass = $pass; $user->addRole('guest'); $user->save(); wire('users')->setCurrentUser($user); تعديل هذا throw new Exception("Could not connect to LDAP"); لهذا throw new WireException($this->_('Could not connect to LDAP')); يودا من حرب النجوم $field = Wire::getFuel('modules')->get('InputfieldText'); لهذا $field = wire('modules')->get('InputfieldText'); Link to comment Share on other sites More sharing options...
ryan Posted February 18, 2012 Share Posted February 18, 2012 I don't know what WillyC was saying above, but his code suggestions are right on. I agree with everything he said (in the code at least). Also, Jim this is one awesome module you've put together. Nice work! Edit: WillyC please use English, if possible. People are reporting your post as spam (and I know it's not, your post was good). Admittedly, I never understand your drunken-refugee-Yoda English, but I think even fewer here understand your Klingon (?) or whatever that is. I do admit it looks very pretty though (as does your beard). But please use English where possible, or at least make us think you are... Ultimately if we can understand your code, that's all that's necessary, and you are doing well there. Link to comment Share on other sites More sharing options...
Adam Kiss Posted February 18, 2012 Share Posted February 18, 2012 ...Klingon... It's arabic, I believe... and particulary for this: 'يودا من حرب النجوم', translate.google.com said it means 'Yoda from Star Wars'. Other than that, I give +1 to using english. We are international here and we won't understand each other, if we start talking our native languages (except Ryan and few others, there would nothing change. ) 1 Link to comment Share on other sites More sharing options...
diogo Posted February 18, 2012 Share Posted February 18, 2012 In arabic, shouldn't the sentences be on the right? Link to comment Share on other sites More sharing options...
Oliver Posted February 18, 2012 Share Posted February 18, 2012 Nice, Jim, even if I have no idea of ldap auth. As I'm working on a module that serves as a kind of manager for different auth modules () and will provide standard login, Twitter and Facebook auth, it would be great to have a ldap auth module for it, too. When you're ok with it, I'd build one based on your code here, as it mostly just needs a bit of reordering. Link to comment Share on other sites More sharing options...
Pete Posted February 18, 2012 Share Posted February 18, 2012 Nice module Jim - this is very handy for one project I've got coming up as I can now integrate it with the company's domain to some degree and not have the hassle of people trying to change/remember their passwords in multiple places. It's also going to be a good starting point for another sooner project that was going to require me to code something very similar, so thanks as that will be coded in no time at all working from your module! In arabic, shouldn't the sentences be on the right? I would have to change a forum setting and that would affect everyone's post, but it's possible to have everything appear right-to-left if you like Link to comment Share on other sites More sharing options...
diogo Posted February 18, 2012 Share Posted February 18, 2012 hm... it's not needed Link to comment Share on other sites More sharing options...
Jim Yost Posted February 18, 2012 Author Share Posted February 18, 2012 Thanks WillyC, that is exactly what I was looking for! The module still needs work with ldap settings (specifically TLS and other connection types that LDAP works with). I just needed it to show my company how flexible ProcessWire is . Oliver, let me get a formal module together that supports more complete features of LDAP before you grab it (though you are welcome to do so). I started one for looking up users, groups, and pulling information as well and will end up tieing the two together. -J Link to comment Share on other sites More sharing options...
Oliver Posted February 18, 2012 Share Posted February 18, 2012 Thanks Jim. I just started the module, so there’s no hurry. Gives me time to get an idea of LDAP. Link to comment Share on other sites More sharing options...
apeisa Posted August 16, 2012 Share Posted August 16, 2012 I tested this in one project and it works great! I implemented the WillyC improvements and added the Session prefix to the name. Code is here: <?php class SessionLdapAuth extends WireData implements Module, ConfigurableModule { public static function getModuleInfo() { return array( "title" => "LDAP Authentication", "version" => 100, "summary" => "Allows uses to be authenticated via LDAP", "permanent" => false, "singular" => true, "autoload" => true ); } public function init() { $this->session->addHookAfter('login', $this, 'login'); } public function login($event) { if ($event->return) return; // they are already in $name = $event->arguments[0]; $pass = $event->arguments[1]; $conn = ldap_connect($this->data['host']); if ($conn) { $bind = @ldap_bind($conn, "$name@{$this->data['accountDomainName']}", $pass); if ($bind) { // success // check if they area lready a user in PW $user = wire('users')->get("name=$name"); if($user->id) { $user->pass = $pass; if($user->isChanged('pass')) $user->save(); $user = wire('session')->login($name, $pass); $event->return = $user; return; } else { // create a new user $user = wire('users')->add($name); $user->pass = $pass; $user->addRole('guest'); $user->save(); wire('users')->setCurrentUser($user); $event->return = $user; return; } } else { // fail $event->return = null; return; } } else { // could not connect throw new WireException($this->_('Could not connect to LDAP')); } } static public function getModuleConfigInputfields(array $data) { $inputfields = new InputfieldWrapper(); $field = wire('modules')->get('InputfieldText'); $field->attr('name', 'host'); $field->label = 'Host'; if (isset($data['host'])) $field->attr('value', $data['host']); $field->description = 'The LDAP server hostname'; $inputfields->append($field); $field = wire('modules')->get('InputfieldText'); $field->attr('name', 'accountDomainName'); $field->label = 'Account Domain Name'; if (isset($data['accountDomainName'])) $field->attr('value', $data['accountDomainName']); $field->description = 'The LDAP server domain'; $inputfields->append($field); $field = wire('modules')->get('InputfieldText'); $field->attr('name', 'accountDomainNameShort'); $field->label = 'LDAP server domain (short)'; if (isset($data['accountDomainNameShort'])) $field->attr('value', $data['accountDomainNameShort']); $field->description = 'The LDAP server hostname'; $inputfields->append($field); $field = wire('modules')->get('InputfieldText'); $field->attr('name', 'baseDn'); $field->label = 'Base DN'; if (isset($data['baseDn'])) $field->attr('value', $data['baseDn']); $field->description = 'The LDAP server DN'; $inputfields->append($field); $field = wire('modules')->get('InputfieldCheckbox'); $field->attr('name', 'startTls'); $field->label = 'Use TLS'; $field->attr('value', 1); if (isset($data['startTls'])) { if ($data['startTls']) $field->attr('checked', true); } $field->description = 'Check this option to enable TLS security'; $inputfields->append($field); return $inputfields; } } 6 Link to comment Share on other sites More sharing options...
ryan Posted August 16, 2012 Share Posted August 16, 2012 Very nice, thanks for posting this! What do you think about putting this on GitHub so that it can be installed through the modules directory? I would do it myself, but have no way of testing LDAP, so don't think my GitHub account would be a good one to have it on. I also know that the original author (JimYost--my brother-in-law) is really busy at work and not likely to post or develop this further. But it seems like a pretty unique and great module, so would be great to have it as something more than a copy/paste, if/when you or someone else using it has time. Link to comment Share on other sites More sharing options...
apeisa Posted August 16, 2012 Share Posted August 16, 2012 Sure. I'll put it to github soon. We have few ideas to develop it further. Things like bringing more user details like email, but most importantly map ad groups to roles. 3 Link to comment Share on other sites More sharing options...
Pete Posted October 30, 2012 Share Posted October 30, 2012 I just used this to add AD login abilities to a company docs intranet site for PW and would like to suggest some changes. In this particular environment, the AD logins are in the format of "Forename Surname" <- the problem here is the space in the middle and PW replaces it with an underscore before the check against the LDAP server so it fails and doesn't authenticate properly. The following fixes it: Replace this: $name = $event->arguments[0]; $pass = $event->arguments[1]; with this: $name = wire('input')->post->login_name; $pass = wire('input')->post->login_pass; And this: $user = wire('users')->get("name=$name" with this: $user = wire('users')->get("name=".$event->arguments[0]); Any other suggestions welcome, but that should work correctly in more situations. Antti, did you do any more work with AD groups mapped to roles? 3 Link to comment Share on other sites More sharing options...
apeisa Posted October 30, 2012 Share Posted October 30, 2012 Antti, did you do any more work with AD groups mapped to roles? Nope, sorry. My need in that project was just the authentication. Link to comment Share on other sites More sharing options...
Pete Posted October 30, 2012 Share Posted October 30, 2012 No worries - just wanted to check I wasn't going to reinvent the wheel before going any further. All I really need that's extra is to pull out the user's name and email address for now - groups is a bit beyond me. I know that using adLDAP I can get more information but I'd rather not use another class just for that. I'll have a tinker and see what I can come up with, but so far this solves a huge problem of not wanting to give users in a Windows domain environment yet another login to remember Link to comment Share on other sites More sharing options...
Nico Knoll Posted August 21, 2013 Share Posted August 21, 2013 Does something have changed in the last year? Link to comment Share on other sites More sharing options...
jaimenadal Posted September 11, 2015 Share Posted September 11, 2015 Please, could someone tell me if I am right or wrong? I'm into a new project at my current job, I've to find a plugin or module for LDAP to keep the session connection. Does LDAP support the sessions? Sorry but I am very new into LDAP. Any suggestion is welcome. Link to comment Share on other sites More sharing options...
kreativmonkey Posted November 24, 2015 Share Posted November 24, 2015 Hallo, how can i change the Module to login every User with LDAP? The Problem is when a User change his LDAP Password, he can login on Processwire with the old password so long he not login with the new Password! That is a big Security Problem. So i will authenticate every User by checking the LDAP. Any Idea? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now