我正在使用带有fos_userbundle和fr3d_ldapbundle的symfony 3.3通过LDAP对我的用户进行身份验证。 如果尝试使用生成的标准登录表单,则登录正常。 但我需要做的是手动(以编程方式)登录。 用fr3d_ldapbundle做到最好的方法是什么?
对不起伙计们,我给你更多详情:
如果我尝试使用 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')
);
}
有人可以帮助我吗? 谢谢。
答案 0 :(得分:0)
@Jon Doe,在进行ldap身份验证时,您当然无法获取有关用户对象的密码信息。 LDAP使用绑定功能,该功能获取用户名和密码信息,尝试进行身份验证并返回成功或失败。
使用FR3DLdapBundle时,这应该在Authentication Provider中完成。检查LdapAuthenticationProvider.php
文件以获取以下代码。
if (!$this->ldapManager->bind($currentUser, $presentedPassword)) {
throw new BadCredentialsException('The credentials were changed from another session.');
}
在您的控制器 - LoginAction中,您不应该进行任何身份验证。 如果您需要具有基于角色的访问权限,请检查是否存在任何身份验证错误并检查任何特定于访问权限的角色。
// 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');