Ок,
Итак для чего я это делал:
На внутренний сайт в компании - поставил VB, чтобы было... Выяснилось одно неудобство - все компьютеры в компании находятся в AD и входят в домен под своими аккаунтами, а при заходе на VB нужно заного регистрироваться и воодить пароль итп... хотя потенциально можно использовать AD для аутентификации... Поискал решение по форумам - ничего хорошего не нашел, пришлось делать самому.
Общий механизм простой -
1. на сервере IIS включается серверная аутентификация,
2. в дальнейшем, в VB при создании сессии проверяется наличие серверной переменной AUTH_USER,
3. при нахождении - делается запрос по LDAP к серверу AD на наличие такого пользователя и доставание различных данных по нему (Email, Имя)
4. Если все предыдущие шаги удались - ищем пользователя соответствующего логину в базе, если есть - создаем cookie с нужной инфой (чтобы в дальнейшем этот механизм не использовать) а если нет - создаем нового пользователя и опять же заходим на форум под этим пользователем с созданием cookie.
программно все делается так:
1. Настраиваем IIS на Integrated Windows Authentication и убираем Anonymous access (хотя это не обязательно - если хотим оставить стандартный вход (по имени паролю).
2. модифицируем файл includes\class_core.php функция конструктор vB_Session:
вставяем после блока
PHP Code:
// or maybe we can use a cookie..
if (($gotsession == false OR empty($session['userid'])) AND $userid AND $password AND !defined('SKIP_SESSIONCREATE'))
{
$useroptions = (defined('IN_CONTROL_PANEL') ? 16 : 0) + (defined('AVATAR_ON_NAVBAR') ? 2 : 0);
$userinfo = fetch_userinfo($userid, $useroptions, $languageid);
if (md5($userinfo['password'] . COOKIE_SALT) == $password)
{
$gotsession = true;
// combination is valid
if (!empty($session['sessionhash']))
{
// old session still exists; kill it
$db->shutdown_query("
DELETE FROM " . TABLE_PREFIX . "session
WHERE sessionhash = '" . $this->registry->db->escape_string($session['sessionhash']). "'
");
}
$this->vars = $this->fetch_session($userinfo['userid']);
$this->created = true;
$this->userinfo =& $userinfo;
}
}
блок аутенификации NTLM:
PHP Code:
// CHECK Server authentification (NTLM)
if (($gotsession == false OR empty($session['userid'])))
{
$HTTP_SERVER_VARS = $_SERVER;
$user = $HTTP_SERVER_VARS["AUTH_USER"];
if ( stristr($user, 'DOMAINNAME\\') ) // Check domain correctness
{
if (!strncmp(strtolower($user),'domainname\\', 11)) // remove domain name from user name
{
$user = substr($user, 11); // 11 - length of doamin name + 1
}
$ldap=new adLDAP($options);
$result=$ldap->user_info("$user");
if( $result["count"] > 0 ) // OK - successfuly found user in LDAP directory
{
$displayName = $result[0]["displayname"][0];
$mail = $result[0]["mail"][0];
// check user existance
if ($ui = $db->query_first("SELECT userid FROM " . TABLE_PREFIX . "user WHERE username = '" . $db->escape_string(htmlspecialchars_uni($user)) . "'"))
{
// ok - can login
$userid = $ui['userid'];
$useroptions = (defined('IN_CONTROL_PANEL') ? 16 : 0) + (defined('AVATAR_ON_NAVBAR') ? 2 : 0);
$userinfo = fetch_userinfo($userid, $useroptions, $languageid);
$gotsession = true;
// combination is valid
if (!empty($session['sessionhash']))
{
// old session still exists; kill it
$db->shutdown_query("
DELETE FROM " . TABLE_PREFIX . "session
WHERE sessionhash = '" . $this->registry->db->escape_string($session['sessionhash']). "'
");
}
$this->vars = $this->fetch_session($userinfo['userid']);
$this->created = true;
$this->userinfo =& $userinfo;
vbsetcookie('userid', $userid, true, true, true);
vbsetcookie('password', md5( $userinfo['password'] . COOKIE_SALT), true, true, true);
}
else
{
// add user and login
// init user datamanager class
$userdata =& datamanager_init('User', $registry, ERRTYPE_ARRAY);
$userdata->set_info('coppauser', 0);
$userdata->set_info('coppapassword', '');
$userdata->set_bitfield('options', 'coppauser', 0);
$userdata->set('parentemail', '');
$userdata->set('password', md5($user."Password23456712"));
$userdata->set('email', $mail);
$userdata->set('username', $user);
// set usergroupid
$userdata->set('usergroupid', 2);
// set languageid
$userdata->set('languageid', 1);
// set user title
$userdata->set_usertitle('', false, 2, false, false);
$userdata->set('showbirthday', 0);
$userdata->set('birthday', array(
'day' => 1,
'month' => 1,
'year' => 1980
));
$dst = 2;
$userdata->set_dst($dst);
$userdata->set('timezoneoffset', 3);
// register IP address
$userdata->set('ipaddress', IPADDRESS);
$userdata->pre_save();
$userid = $userdata->save();
$useroptions = (defined('IN_CONTROL_PANEL') ? 16 : 0) + (defined('AVATAR_ON_NAVBAR') ? 2 : 0);
$userinfo = fetch_userinfo($userid, $useroptions, $languageid);
$gotsession = true;
// combination is valid
if (!empty($session['sessionhash']))
{
// old session still exists; kill it
$db->shutdown_query("
DELETE FROM " . TABLE_PREFIX . "session
WHERE sessionhash = '" . $this->registry->db->escape_string($session['sessionhash']). "'
");
}
$this->vars = $this->fetch_session($userinfo['userid']);
$this->created = true;
$this->userinfo =& $userinfo;
vbsetcookie('userid', $userid, true, true, true);
vbsetcookie('password', md5( $userinfo['password'] . COOKIE_SALT), true, true, true);
}
}
}
}
Если будете использовать - не забудьте поменять DOMAINNAME и domainname на короткое имя вашего домена.
3. выкладываем библиотеку adLDAP.php в корень форума.
http://adldap.sourceforge.net/
в этом файле можно ввести данные для доступа к LDAP репозиторию по умолчанию, или использовать опции в конструкторе adLDAPа...
Пример изменения adLDAP.php
PHP Code:
// You can set your default variables here, or when you invoke the class
var $_account_suffix="@microsoft.ru";
var $_base_dn = "DC=microsoft,DC=ru";
// An array of domain controllers. Specify multiple controllers if you
// would like the class to balance the LDAP queries amongst multiple servers
var $_domain_controllers = array ("microsoft.ru");
// optional account with higher privileges for searching
// not really that optional because you can't query much as a user
var $_ad_username="TestUser";
var $_ad_password="TestPassword";
4. включаем в PHP.ini модуль php_ldap
По идее все... посе этого все должно заработать...