简体   繁体   中英

How programmatically login with fr3d_ldapbundle

I am using symfony 3.3 with fos_userbundle and fr3d_ldapbundle to authentichate my users trough LDAP. The login works correctly if a try to use the standard login form generated. But what I need to do is a manual(programmatically) login. What is the best way to do it with fr3d_ldapbundle?

Sorry guys, I give you more details:

I tried to follow this guide: https://ourcodeworld.com/articles/read/459/how-to-authenticate-login-manually-an-user-in-a-controller-with-or-without-fosuserbundle-on-symfony-3

If I try to use the fos_user.user_manager the login works correctly, but using the fr3d_ldap.ldap_manager it doesn't work. (the isPasswordValid function return me "Username or Password not valid")

The user is retrieved correctly from LDAP server, but the "password" field is empty if I print the $user object. Using the standard login form the authentication works correctly and the username is stored in my fos user bundle table with the password field empty. Could be this my problem?

Also the $salt is empty.

This is my code of 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')
    );
}

Someone is able to help me? Thank you.

@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');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM