0

我正在使用 symfony 3.3 和 fos_userbundle 和 fr3d_ldapbundle 来通过 LDAP 验证我的用户。如果尝试使用生成的标准登录表单,登录将正常工作。但我需要做的是手动(以编程方式)登录。使用 fr3d_ldapbundle 的最佳方法是什么?

对不起,伙计们,我给你更多的细节:

我尝试遵循本指南:https ://ourcodeworld.com/articles/read/459/how-to-authenticate-login-manually-an-user-in-a-controller-with-or-without-fosuserbundle-on -symfony-3

如果我尝试使用fos_user.user_manager登录正常工作,但使用fr3d_ldap.ldap_manager它不起作用。(isPasswordValid函数返回“用户名或密码无效”)

从 LDAP 服务器正确检索用户,但如果我打印$user对象,“密码”字段为空。使用标准登录表单,身份验证工作正常,用户名存储在我的 fos 用户捆绑表中,密码字段为空。这可能是我的问题吗?

$salt也是空的。

这是我的 LoginAction 代码:

public function loginAction(Request $request)
{
    // This data is most likely to be retrieven from the Request object (from Form)
    // But to make it easy to understand ...
    $_username = "user";
    $_password = "password";

    // Retrieve the security encoder of symfony
    $factory = $this->get('security.encoder_factory');

    /// Start retrieve user
    // Let's retrieve the user by its username:
    /*
    // If you are using FOSUserBundle:
    $user_manager = $this->get('fos_user.user_manager');
    $user = $user_manager->findUserByUsername($_username);
    //Or by yourself
    $user = $this->getDoctrine()->getManager()->getRepository("ApiBundle:User")
            ->findOneBy(array('username' => $_username));
    */
    //Using fr3d/ldap-bundle 
    $user_manager = $this->get('fr3d_ldap.ldap_manager');
    $user = $user_manager->findUserByUsername($_username);
    //print_r($user);die();
    /// End Retrieve user

    // Check if the user exists !
    if(!$user){
        return new Response(
            'Username doesnt exists',
            Response::HTTP_UNAUTHORIZED,
            array('Content-type' => 'application/json')
        );
    }

    /// Start verification
    $encoder = $factory->getEncoder($user);
    $salt = $user->getSalt();

    if(!$encoder->isPasswordValid($user->getPassword(), $_password, $salt)) {
        return new Response(
            'Username or Password not valid.',
            Response::HTTP_UNAUTHORIZED,
            array('Content-type' => 'application/json')
        );
    } 
    /// End Verification

    // The password matches ! then proceed to set the user in session

    //Handle getting or creating the user entity likely with a posted form
    // The third parameter "main" can change according to the name of your firewall in security.yml
    $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
    $this->get('security.token_storage')->setToken($token);

    // If the firewall name is not main, then the set value would be instead:
    // $this->get('session')->set('_security_XXXFIREWALLNAMEXXX', serialize($token));
    $this->get('session')->set('_security_main', serialize($token));

    // Fire the login event manually
    $event = new InteractiveLoginEvent($request, $token);
    $this->get("event_dispatcher")->dispatch("security.interactive_login", $event);

    /*
     * Now the user is authenticated !!!! 
     * Do what you need to do now, like render a view, redirect to route etc.
     */
    return new Response(
        'Welcome '. $user->getUsername(),
        Response::HTTP_OK,
        array('Content-type' => 'application/json')
    );
}

有人能帮助我吗?谢谢你。

4

1 回答 1

0

@Jon Doe, you certainly cannot get the password information on user object while doing ldap authentication. LDAP uses bind function which takes username and password information, tries to authenticate and return success or failure.

While using FR3DLdapBundle, this should be done inside Authentication Provider. Check LdapAuthenticationProvider.php file for following code.

if (!$this->ldapManager->bind($currentUser, $presentedPassword)) {
    throw new BadCredentialsException('The credentials were changed from another session.');
}

In your controller - LoginAction you shouldn't be doing any authentication. Just check for any authentication error and check for any access specific role if you need to have role based access as following example.

// get the login error if there is one
$error = $this->get('security.authentication_utils')->getLastAuthenticationError();

// last username entered by the user
$lastUsername = $this->get('security.authentication_utils')->getLastUsername();

//if you need to check for the user role.
$roleGranted = $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN');
于 2018-01-29T14:53:00.777 回答