首先事先声明:发布的代码片段都是基本示例。您需要自己处理琐碎的异常和进一步的逻辑。
我将发布一个快速 hack,以使用 Yii2 高级模板实现简单的 AD 身份验证,该模板将采用用户名/密码并针对 MS Active Directory 域控制器验证此组合。此外,它还会检查用户给定的组成员身份,因此只有具有该组的用户才能登录。
我们假设:
- 用户(特别是用户名)必须存在于当前用户表中(查看授权指南以构建
rbac结构)。我们进一步假设我们数据库中的用户名与您要针对 AD 进行身份验证的用户名相同。
- 您已经为 Yii2 正确设置了Adldap2包装器(如alexevdv/yii2-adldap)或将 Adladp2 作为供应商模块加载。从包装器中受益: 您可以在应用程序配置的组件部分中配置 adldap2 类,然后您可以将包装器用作 Yii2 组件。
- 您的 PHP 环境使用 LDAP 扩展(例如在 debian 发行版上运行类似apt-get install php5-ldap的东西)。
- 您有一些管理员凭据可以连接到具有以您想要的方式查询 AD 的权限的域控制器。
因此,让我们从基本设置开始。
设置包装器配置(例如 config/main-local.php)。
'components' => [
'ldap' => [
'class' => 'alexeevdv\adldap\Adldap',
'options' => [
'account_suffix' => '@stackoverflow.com',
'domain_controllers' => ['dc1.stackoverflow.com', 'dc2.stackoverflow.com'],
'base_dn' => 'dc=stackoverflow,dc=com',
'admin_username' => 'someusername',
'admin_password' => 'somepassword',
'use_ssl' => true,
'port' => '636'
],
],
],
我想在 ldap 和本地身份验证之间轻松切换。配置一些本地参数以具有全局可访问的应用程序参数(例如 config/params-local.php)。
return [
'adminEmail' => 'admin@example.com',
'authOverLdap' => true,
'ldapGroup' => 'someldapgroup',
];
编辑您的 LoginForm.php,尤其是validatePassword函数(例如 common/models/LoginForm.php)。
/**
* Validates the password.
* This method serves as the inline validation for password.
* If the authOverLdap attribute is set in the params config,
* user and password will be authenticated over ldap
*
* @param string $attribute the attribute currently being validated
* @param array $params the additional name-value pairs given in the rule
*/
public function validatePassword($attribute, $params)
{
if (!$this->hasErrors()) {
$user = $this->getUser();
// to switch between the auth-methods
$authOverLdap = \Yii::$app->params['authOverLdap'];
if ($authOverLdap) {
if (!$user || !$user->validateCredentialsOverLdap($user->username, $this->password)) {
$this->addError($attribute, 'Some error text.');
}
} else {
if (!$user || !$user->validatePassword($this->password)) {
$this->addError($attribute, 'Some error text.');
}
}
}
}
在处理 LDAP 身份验证的用户模型中添加validateCredentialsOverLdap函数(例如 /common/models/User.php)。
/**
* Validates a user/password combination over ldap
*
* @param string $username username to validate over ldap
* @param string $password password to validate over ldap
* @return boolean if the provided credentials are correct and the user is a member of **ldapGroup**
*/
public function validateCredentialsOverLdap($username, $password)
{
$authSuccess = false;
// checking the supplied credentials against the ldap (e.g. Active Directory)
// first step: the user must have a valid account
// second step: the user must be in a special group
$authOk = \Yii::$app->ldap->authenticate($username, $password);
if ($authOk) {
$adUser = \Yii::$app->ldap->users()->find($username);
// the user must be in special group (set in Yii params)
if($adUser->inGroup(\Yii::$app->params['ldapGroup'])) {
$authSuccess = true;
}
}
return $authSuccess;
}
免责声明:
- 不要复制和粘贴这些片段!你必须知道你在做什么!
- 这将向您展示一个示例,并为您提供使用包装器和 Yii2 框架实现 AD 身份验证的提示。
- 我在围墙花园内联网中运行此代码!
- 永远使用SSL等安全层通过 LDAP 进行通信!您不知道谁在嗅探您可能安全的网络中的流量。您处理用户凭据。这可能是个大问题,尤其是在单点登录环境中!别傻了。