Yii2 ldap身份验证后设置

Yii2 ldap identity set up after authentication

我是 Yii2 的新手,我需要使用 ldap 创建一个登录系统。关于它的信息不多,所以我希望有人能帮助我。

我安装了 edvlerblog/yii2-adldap-module 并且我已经成功实施了身份验证。

我的问题是,我希望在登录后拥有与使用高级模板相同的用户身份,并能够使用 Yii::$app->user 功能。

官方示例创建的User实现了IdentityInterface但是通过ActiveRecord:

http://www.yiiframework.com/doc-2.0/yii-web-identityinterface.html

我还找到了很多参考 Yii 版本 1 的例子。这个很好:

https://www.exchangecore.com/blog/yii-active-directory-useridentity-login-authentication/

但仍然无法使它工作...可能是概念问题或语法问题,但无论如何我真的很感谢这里的帮助。

models/LoginForm.php认证方式:

public function validatePasswordLdap($attribute, $params)
{
    if (!$this->hasErrors()) {
        $user = $this->getUserLdap();
        if (!$user || !Yii::$app->ldap->authenticate($this->username,$this->password)) {
            $this->addError($attribute, 'Incorrect username or passwords.');
        }
    }
}

models/LoginForm.php登录方式:

public function loginLdap()
{
    if ($this->validate()) {
        return Yii::$app->user->login($this->getUserLdap(), $this->rememberMe ? 3600 * 24 * 30 : 0);
    } else {
        return false;
    }
}

最后一个,getUser 方法。 UserLdap 正在实施 IdentityInterface,但我不知道如何正确执行:

public function getUserLdap()
{
    if ($this->_user === false) {           
        $this->_user = UserLdap::findIdentity($this->username);
    }

    return $this->_user;
}

终于明白其中的逻辑了:

  • 当您在 LoginForm.php 视图中登录时,获取用户名和密码并使用 validatePasswordLdap 进行验证。您必须在规则中指定哪个函数正在验证密码。

  • 然后如果 validate() 成功,它会使用登录中引入的用户名调用 FindIdentity。此函数必须 return 一个 IdentityInterface 对象,因此首先您需要创建用户对象,设置参数(电子邮件、电话、姓名等)并 return 它。

  • 要在整个站点中使用 login/logout 功能和 isGuest,您只需按照下面的 loginLdap 函数进行操作,并将此用户对象传递给 Yii::$app->user ->登录方法。

代码如下所示:

LoginForm.php

public function rules()
{
    return [
        // username and password are both required
        [['username', 'password'], 'required'],
        // rememberMe must be a boolean value
        ['rememberMe', 'boolean'],
       // password is validated by validatePassword()
        ['password', 'validatePasswordLdap'],
    ];
}


public function validatePasswordLdap($attribute, $params)
{
    if (!$this->hasErrors()) {
        $user = $this->getUserLdap();
        if (!$user || !Yii::$app->ldap->authenticate($this->username,$this->password)) {
            $this->addError($attribute, 'Incorrect username or passwords.');
        }
    }
}

public function loginLdap()
{
    if ($this->validate()) {
        return Yii::$app->user->login($this->getUserLdap(), $this->rememberMe ? 3600 * 24 * 30 : 0);
    } else {
        return false;
    }
}

User.php

public static function findIdentity($id)
{

    $new_identity = new User();

    if ($user_ldap_info = Yii::$app->ldap->user()->infoCollection($id, array("*"))){
        $new_identity->setId($user_ldap_info->samaccountname);
        $new_identity->setEmail($user_ldap_info->mail);
        $new_identity->setUsername($user_ldap_info->displayName);   
    }

    return $new_identity;
}

public function setEmail($email)
{
    $this->email = $email;
}

public function setUsername($username)
{
    $this->username = $username;
}

public function setId($id)
{
    $this->id = $id;
}

里面LoginForm.php

public function getUserLdap()
{
    if ($this->_user === false) {           
        $this->_user = User::findIdentity($this->username);
    }

    return $this->_user;
}

编辑:由于供应商 ADLDAP 更新,我不得不将 findIdentity 更改为:

public static function findIdentity($id)
{
    $new_identity = new User ();

    if ( $user_ldap_info = Yii::$app->ldap->users()->find($id) ) {
        $new_identity->setId ( $user_ldap_info->samaccountname [0] );
        $new_identity->setEmail ( $user_ldap_info->mail[0] );
        $new_identity->setUsername ( $user_ldap_info->givenname [0] );
    }

    return $new_identity;
}

我希望 Daniel Stolf 发表了他所描述的工作示例。

在搜索时,我想知道是否已使用最新的 Larvel 5.1 完成并找到了这个:

https://libraries.io/github/sroutier/laravel-5.1-enterprise-starter-kit

Optional LDAP/AD authentication using sroutier/eloquent-ldap, with options to:

Automatically creates local account for LDAP/AD users on first login.
Automatically assign to matching local roles based on LDAP/AD group membership.
Refresh role assignment on login.

这正是我要找的东西。我更喜欢使用 Yii2 框架,但我想我会转向 Laravel,因为缺少这样的一体化扩展功能对于 Yii2.

除非 Konrad 亲切地为 Yii2 重写本指南: http://blog.realhe.ro/windows/yii-role-mapping-based-on-active-directory

首先事先声明:post编辑的代码片段都是基本示例。您需要自己处理琐碎的异常和进一步的逻辑。


我会post一个fast hack用Yii2 advance模板实现一个简单的AD认证,这将需要一个username/password并对这个组合进行认证针对 MS Active Directory 域控制器。此外,它还会检查用户的给定组成员身份,因此只有拥有该组的用户才能登录。

我们假设:

  • 用户(特别是用户名)必须存在于当前 用户 table(查看 Authorization Guide 以构建 rbac 结构)。我们进一步假设我们数据库中的 用户名 与您要针对 AD 进行身份验证的用户名相同。
  • 您已正确设置 Adldap2 wrapper for Yii2 (like alexeevdv/yii2-adldap) 或加载 Adladp2 作为供应商模块。 包装器的好处:您可以在应用程序配置的组件部分配置 adldap2 class,然后您可以使用包装器作为 Yii2 组件。
  • 你的 PHP-Environment 使用 LDAP-Extension(例如 运行 debian 上的 apt-get install php5-ldap发行版)。
  • 您有一些 管理员凭据 可以连接到域控制器,并有权以您想要的方式查询 AD。

那么,让我们从基本设置开始吧。

设置包装器配置(例如 config/main-local.php)。

'components' => [
    'ldap' => [
        'class' => 'alexeevdv\adldap\Adldap',
        'options' => [
            'account_suffix' => '@whosebug.com',
            'domain_controllers' => ['dc1.whosebug.com', 'dc2.whosebug.com'],
            'base_dn' => 'dc=Whosebug,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 进行通信!您不知道谁在 嗅探 您可能 安全 网络中的流量。您处理用户凭据。这可能是个大问题,尤其是在单点登录环境中!别傻了。