LDAP Auth for Session login
#1
Posted 17 February 2012 - 05:00 PM
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
#2
Posted 17 February 2012 - 05:01 PM
<?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;
}
}
#3
Posted 17 February 2012 - 05:37 PM
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.
#4
Posted 17 February 2012 - 05:58 PM
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');
#5
Posted 17 February 2012 - 11:27 PM
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.
#6
Posted 18 February 2012 - 09:10 AM
...Klingon...
#8
Posted 18 February 2012 - 09:58 AM
As I'm working on a module that serves as a kind of manager for different auth modules (http://processwire.c...-twitter-oauth/) 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.
#9
Posted 18 February 2012 - 02:01 PM
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
#11
Posted 18 February 2012 - 02:41 PM
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
#13
Posted 16 August 2012 - 04:26 AM
<?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;
}
}
#14
Posted 16 August 2012 - 08:00 AM
#15
Posted 16 August 2012 - 08:56 AM
#16
Posted 30 October 2012 - 11:37 AM
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?
#17
Posted 30 October 2012 - 12:14 PM
Antti, did you do any more work with AD groups mapped to roles?
Nope, sorry. My need in that project was just the authentication.
#18
Posted 30 October 2012 - 02:04 PM
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
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users













