【问题标题】:Create user but checking if exist in Active Directory with PHP创建用户但使用 PHP 检查 Active Directory 中是否存在
【发布时间】:2016-12-12 18:12:09
【问题描述】:

我正在使用 Symfony 2.8.2,Doctrine。

我需要在我的应用数据库中创建用户,但首先我需要检查这些用户是否存在于外部 Active Directory 数据库中。只有当用户存在时,才有可能在应用数据库上创建用户。我的代码适用于创建用户,但现在我正在尝试实现“首先检查用户是否存在”部分,我正在关注一些示例,但我不确定我的做法是否顺利。我读过 LDAP 的通常顺序是连接、绑定、搜索、解释搜索结果、关闭连接。有人可以提示我应该如何处理我的代码,我应该先在哪里进行搜索,在绑定之前还是之后?以及为什么。

public function createAction(Request $request){
    $em = $this->getDoctrine()->getManager();
    $post_send = $request->request->get('userbundle_user');

    if (array_key_exists('id', $post_send)) {
        $ldap_success = true;
        $entity = $em->getRepository('UserBundle:User')->find($post_send['id']);
    }else{
        $ldapconn = ldap_connect("10.0.0.230");
        $Pass= "XXXXXX";
        $searchUser = "YYYYYY";
        $ldap_success = false;
        if (@ldap_bind($ldapconn, $searchUser, $Pass)) {
            try{
                $post_send['password'] = $Pass;
                $attributes = ['cn'];
                $filter = "(&(objectClass=user)(objectCategory=person)(userPrincipalName=".ldap_escape($post_send['username'], null, LDAP_ESCAPE_FILTER)."))";
                $baseDn = "DC=XXX,DC=XX,DC=cl";
                $results = @ldap_search($ldapconn, $baseDn, $filter);
                //$info = @ldap_get_entries($ldapconn, $results);
                if ( $results ) {
                    $ldap_success = true;
                } else {
                    $ldap_success = false;//false, lo deje en true para que pudiera avanzar
                }
            }
            catch(\Exception $e){
                $ldap_success = false;
            }
        }
        $entity = new User();
    }

    if( $ldap_success ){
        $entity->setUsername($post_send['username']);
        $entity->setRut($post_send['rut']);
        //$entity->setSalt("ssss");
        if (array_key_exists('password', $post_send)) {
            if ( $post_send['password'] != "" ) {
                $entity->setPassword($post_send['password']);
                $this->setSecurePassword($entity);
            }
        }
        $entity->setEmail($post_send['email']);
        $entity->setDateAdded(new \DateTime());
        $entity->setIsActive(true);
        $entity->setIsAdmin(true);
        $entity->setUserRoles($em->getRepository('UserBundle:Role')->find( $post_send['admin_roles_id'] ));
        $entity->setWizardCompleted(true);
        $entity->setPath("s");
        $em->persist($entity);
        $em->flush();
        $json = new JsonUtils();
        return $json->arrayToJson(array("id"=>$entity->getId()));
    }
    return $json->arrayToJson( array("sueccess"=>false ) );
}

这里有一个问题How do I make a ldap search with anonymous binding? 与我的问题有关,完全没有答案。

【问题讨论】:

  • 是登录站点的用户的$post_send['username']$post_send['password'] 凭据吗?如果出现这种情况,您真正需要做的就是验证 ldap_bind() 是否有效。您还可以使用内置的 LDAP componentLdapTools 之类的捆绑包。
  • 不,是新参数,它们来自“创建新用户”表单。但是绑定工作正常。到目前为止,我还没有验证我要创建的用户是否存在于 AD 中,但我在登录系统时使用了绑定。
  • 好的,我现在明白了。我没有意识到这是在控制器中。哎呀。我认为您真正需要的是一个 LDAP 服务帐户,它只是“域用户”组的成员(因此具有只读访问权限)。然后,您可以使用该帐户的用户名/密码进行绑定和查询,以查看他们尝试在表单中创建的用户名是否确实存在于 AD 中。

标签: php symfony active-directory doctrine ldap


【解决方案1】:

关于您的 AD 查询以检查用户是否存在(从您的 else 语句的开头开始),我将使逻辑如下所示:

$ldapconn = ldap_connect("10.0.0.230");
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0)
// Use a LDAP service account with only read access...
$searchUser = 'user@myDomain.com';
$searchPass = '12345';

$ldap_success = false;
if (@ldap_bind($ldapconn, $searchUser, $searchPass)) {
    $attributes = ['cn'];
    $filter = "(&(objectClass=user)(objectCategory=person)(userPrincipalName=".ldap_escape($post_send['username'], null, LDAP_ESCAPE_FILTER)."))";
    $baseDn = "DC=myDomain,DC=com";
    $results = @ldap_search($ldapconn, $baseDn, $filter, $attributes);
    $info = @ldap_get_entries($ldapconn, $results);

    $ldap_success = ($info && $info['count'] === 1);
}

在这种情况下,$ldap_success 只会是 true,如果用户存在于 AD 中并指定了 UPN

但是,如果您需要用户的密码并绑定到 AD,则没有理由还验证绑定后是否可以通过查询找到该用户。在这种情况下,只需绑定到 AD 就足以证明它们存在于 AD 中。

【讨论】:

  • 谢谢,我正在检查这个。不,我不再需要用户的密码。我只需要检查通过邮件传递的用户名。我将修改表单,因为不再需要密码。我认为你的回答会奏效。
  • 我找不到使用该代码的用户。它总是返回错误的 $results。绑定没问题。我当然在使用我的 $baseDn = "DC=XXXXX,DC=XX,DC=cl";
  • 添加var_dump($post_send['username']),这表明什么?用户名必须采用“电子邮件”格式(即username@domain.com)。
  • 我使用的是 samaccountname,所以人们不需要输入整个 name@domain。谢谢,您的代码现在是我解决方案的主要结构。一切正常。我会选择一个正确的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 2015-01-02
  • 2019-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-17
相关资源
最近更新 更多