PDA

View Full Version : Seamless integration of DP into Active Directory


CasN
10-01-07, 08:36 PM
We were missing a logon option, the one where the user is automatically logged like the PostNuke one but now in corporation with AD.
This can be achieved by doing the following:
1. Take away anonymous access on the DP website. Arrange access to this website thru AD controls.
2. Make sure integrated windows authentication is enabled.
3. First document for this website should be index.htm (this one should be before index.php)
4. create an index.htm script in the DP directory which redirects to index.php?login=ad
Change this to index.php?login=pn if you want to use the PN setting for this functionality
5. index.php should be adjusted like:
This is the login routine

if (isset($_REQUEST['login'])) {

$username = dPgetParam( $_POST, 'username', '' );
$password = dPgetParam( $_POST, 'password', '' );
$redirect = dPgetParam( $_REQUEST, 'redirect', '' );

// ad integration start
if ($_REQUEST['login']=='ad'){
// if ($_REQUEST['login']=='pn'){
if ( isset($_SERVER['AUTH_USER'])) {
$temp = explode('\\\\', $_SERVER['AUTH_USER']); //remove the domain name from AUTH_USER
if ($temp[1] == "") {
$adname = $temp[0];
} else {
$adname = $temp[1];
}
}
$username = $adname;
$password = ranpass();
$redirect = 'index.php';
}
// ad integration end
$AppUI->setUserLocale();
@include_once( "$baseDir/locales/$AppUI->user_locale/locales.php" );
@include_once "$baseDir/locales/core.php";
$ok = $AppUI->login( $username, $password );
if (!$ok) {
$AppUI->setMsg( 'Login Failed');
} else {
//Register login in user_acces_log
$AppUI->registerLogin();
}
addHistory('login', $AppUI->user_id, 'login', $AppUI->user_first_name . ' ' . $AppUI->user_last_name);
$AppUI->redirect( "$redirect" );
}

And the following routine should be added at the end of index.php

function ranpass($len = "8"){
$pass = NULL;
for($i=0; $i<$len; $i++) {
$char = chr(rand(48,122));
while (!ereg("[a-zA-Z0-9]", $char)){
if($char == $lchar) continue;
$char = chr(rand(48,90));
}
$pass .= $char;
$lchar = $char;
}
return $pass;
}


6. classes/authenticator.class.php should be adjusted like:
This is at the start

function &getAuth($auth_mode)
{
switch($auth_mode){
// ad integrationstart
case "ad":
$auth = new AdAuthenticator();
return $auth;
break;
// ad integration end
case "ldap":
$auth = new LDAPAuthenticator();
return $auth;
break;
case "pn":
$auth = new PostNukeAuthenticator();
// $auth = new AdAuthenticator(); return $auth;
break;
default:
$auth = new SQLAuthenticator();
return $auth;
break;
}
}

Add the following code to the end of the script

class AdAuthenticator extends SQLAuthenticator
{

function AdAuthenticator()
{
global $dPconfig;
// $this->fallback = isset($dPconfig['postnuke_allow_login']) ? $dPconfig['postnuke_allow_login'] : false;
$this->fallback = isset($dPconfig['ad_allow_login']) ? $dPconfig['ad_allow_login'] : false; }

function authenticate($username, $password)
{
global $db, $AppUI;


if ( !isset($_SERVER['AUTH_USER'])) {
if ($this->fallback)
return parent::authenticate($username, $password);
else {
die($AppUI->_('You have not configured your Website site correctly'));
}
}


// Now we need to check if the user already exists, if so we just
// update. If not we need to create a new user and add a default
// role.
if ($this->userExists($username)){
$this->user_id = $this->userID($username);
$this->username= $username;
$q = new DBQuery;
$q->clear();
$q->addTable('users');
$q->addUpdate('user_password', $password);
$q->addWhere("user_id = {$this->user_id}");
if (! $q->exec()) {
die($AppUI->_('Could not update user credentials'));
}
$q->clear();
return true;
}else{
$this->createsqluser($username, $password);
}
return true;
}

function userExists($username)
{
GLOBAL $db;
$q = new DBQuery;
$result = false;
$q->addTable('users');
$q->addWhere("user_username = '$username'");
$rs = $q->exec();
if ($rs->RecordCount() > 0)
$result = true;
$q->clear();
return $result;
}

function userId($username)
{
GLOBAL $db;
$q = new DBQuery;
$q->addTable('users');
$q->addWhere("user_username = '$username'");
$rs = $q->exec();
$row = $rs->FetchRow();
$q->clear();
return $row["user_id"];
}

function createsqluser($username, $password)
{
GLOBAL $db, $AppUI;

require_once($AppUI->getModuleClass("contacts"));

$c = New CContact();
$c->contact_first_name = $username;
$c->contact_last_name = $username;
$c->contact_email = $username;
$c->contact_order_by = "$username, $username";

db_insertObject('contacts', $c, 'contact_id');
$contact_id = ($c->contact_id == NULL) ? "NULL" : $c->contact_id;
if (! $c->contact_id)
die($AppUI->_('Failed to create user details'));

$q = new DBQuery;
$q->addTable('users');
$q->addInsert('user_username',$username );
$q->addInsert('user_password', $password);
$q->addInsert('user_type', '1');
$q->addInsert('user_contact', $c->contact_id);
if (! $q->exec())
die($AppUI->_('Failed to create user credentials'));
$user_id = $db->Insert_ID();
$this->user_id = $user_id;
$q->clear();

$acl =& $AppUI->acl();
$acl->insertUserRole($acl->get_group_id('anon'), $this->user_id);
}
}


That is effectively all. As you can see in the code, i did introduce a nel logon method called 'ad'. This would make it ease for te developers to use this code and make it standard available. All is needed in addition is to add these options into the config.

If you really want it now and you do not use the PostNuke option, you can easily adjust this code to make it work under the 'pn' setting. (I have made those lines BOLD)

One word about security, important here is clearly that you control access to the home-directory of DP properly. The DP passwords are each time generated at random to increase security levels.
All the above has been done with DP 2.0.4

We find it very usefull, perhaps there are more people around.

Cas

ejrr
11-01-07, 06:43 PM
I will try.

Many tks for you share....

ejrr

Rainer
12-12-07, 06:14 PM
Hi,

has anybody done this with dp 2.1 ?

I followed your instructions however I alway get the following errror:
"You have chosen to log in using an unsupported or disabled login method ldap"

Authentification against AD works

Any ideas ?

Tx

Rainer

ajdonnison
12-12-07, 06:58 PM
If the Active Directory login is incorporated at the web server level, why not just use the HTTP auth method instead?

Rainer
12-12-07, 08:26 PM
If the Active Directory login is incorporated at the web server level, why not just use the HTTP auth method instead?

Well, I'm not that much the apache or php freak :-(
so could you please point me to some links / howtos where I can find
more info on what you mean :-)

Tx

Rainer

ajdonnison
12-12-07, 09:20 PM
Not being a Windows person, I can't really help, but if it provides for HTTP Basic Authentication then you can hook into it by setting dP to use the same (HTTP Basic is one of the options in the authentication drop-down). You do need to provide the realm, if I remember correctly.