YII2: авторизация через Active Directory в шаблоне basic
Почти наверняка это делается легко и не принужденно, каким то другим способом, более стандартным, но: Мы не ищем легких путей (с). Поэтому велосипед.
Для начала в файле params.php добавим настройки необходимые для соединения с AD:
1 2 3 |
return [ "ldap_server"=>"wrfwerfwer.ru", ]; |
Далее изменим модель User.php следующим образом, добавив в него следующие функции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
/** * Проверяем логин-пароль используя AD. Если в БД такого пользователя нет, до добавляем * @param type $username * @param type $password * @return null/int если авторизация удалась возвращаем id из БД. */ public static function AuthByAD($username,$password){ $params = require(__DIR__ . '/../config/web.php'); $value = \yii\helpers\ArrayHelper::getValue($params, 'params'); $ldap_con = ldap_connect($value["ldap_server"]) or die("Could not connect to LDAP server."); // Устанавливаем флажки протокола ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3); // AD Windows 2003 и выше ldap_set_option($ldap_con, LDAP_OPT_REFERRALS, 0); //Определяет, следовать ли автоматически рефералам, возвращенным сервером LDAP. Зачем нужно - не понятно // авторизуемся в AD $ldapbind = @ldap_bind($ldap_con, $username."@".$value["ldap_server"], $password); if ($ldapbind==false) return null; $user_id=SELF::GetIdByLoginFromDB($username); if ($user_id!=null) return $user_id; //если такого логина нет в БД, то добавляем.. $res=(new \yii\db\Query())->createCommand()->insert('users', ['login' =>$username])->execute(); if ($res==false){ die("Не удалось вставить запись с новым пользователем..Увы и ах.."); }; $user_id=$this->GetIdByLoginFromDB($username); if ($user_id!=null) return $user_id; return null; } /** * Получаем id пользователя по логину из БД * @param type $login * @return type null/id null если пользователь не найден */ public static function GetIdByLoginFromDB($login){ $rows = (new \yii\db\Query())->select(['id'])->from('users')->where(['login' => $login])->limit(1)->all(); if (count($rows)>0) { return $rows[0]["id"]; } else { return null; }; } /** * Получить расширенную информацию о пользователе БД по его ID * @param type $id * @return string */ public static function GetExtendInfoByIdFromDB($id){ $rows = (new \yii\db\Query())->select(['id',"login","name","photo","email","last_updated"])->from('users')->where(['id' => $id])->limit(1)->all(); if (count($rows)>0) { $rows[0]["username"]=$rows[0]["login"]; $rows[0]["password"]=""; $rows[0]["authKey"]=$rows[0]["id"]."key"; $rows[0]["accessToken"]=$rows[0]["id"]."-token"; return $rows[0]; } else { return null; }; } |
И там-же заменим функцию:
1 2 3 4 5 6 7 8 9 10 11 |
public static function findIdentity($id) { $arr=self::GetExtendInfoByIdFromDB($id); $res=new User(); $res->id=$arr["id"]; $res->username=$arr["username"]; $res->password=$arr["password"]; $res->authKey=$arr["authKey"]; $res->accessToken=$arr["accessToken"]; return $res; } |
В модели LoginFrom.php изменим функцию login():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public function login() { $user_id=User::AuthByAD(Yii::$app->request->post()["LoginForm"]["username"],Yii::$app->request->post()["LoginForm"]["password"]); if ($user_id==null) { $this->addError("password", 'Не верный пароль или логин'); return false; }; $extended_info=User::GetExtendInfoByIdFromDB($user_id); $tuser=new User(); $tuser->id=$extended_info["id"]; $tuser->username=$extended_info["username"]; $tuser->password=$extended_info["password"]; $tuser->authKey=$extended_info["authKey"]; $tuser->accessToken=$extended_info["accessToken"]; return Yii::$app->user->login($tuser, $this->rememberMe ? 3600*24*30 : 0); } |
В результате получим собственно возможность авторизации через AD, с сохранением пользователя AD если такового в БД нет, в базе данных.