I'm struggling trying to make authentication work after having followed the Symfony2 documentation. I always get bad credential on every attempt to login in. I've looked around and found several cases that were due to a short password or salt field length in the database. That is not my case since i'm creating fields with 250 characters length. Here's what i get from logs
doctrine.DEBUG: SELECT i0_.id AS id0, i0_.username AS username1, i0_.email AS email2, i0_.password AS password3, i0_.salt AS salt4, i0_.is_active AS is_active5, i1_.id AS id6, i1_.name AS name7, i1_.role AS role8 FROM iw_users i0_ LEFT JOIN user_userroles u2_ ON i0_.id = u2_.user_id LEFT JOIN iw_user_roles i1_ ON i1_.id = u2_.userroles_id WHERE i0_.username = ? OR i0_.email = ? ["test2","test2"] []
security.yml
security:
encoders:
Iw\SecurityBundle\Entity\User:
algorithm: sha512
encode_as_base64: true
iterations: 1
# Symfony\Component\Security\Core\User\User: plaintext
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ]
providers:
administrators:
entity: { class: IwSecurityBundle:User }
firewalls:
admin_area:
pattern: ^/admin
http_basic: ~
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: login
check_path: login_check
logout:
path: /logout
target: /
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
login action
public function loginAction(Request $request)
{
$session = $request->getSession();
// get the login error if there is one
if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(
SecurityContextInterface::AUTHENTICATION_ERROR
);
} elseif (null !== $session && $session->has(SecurityContextInterface::AUTHENTICATION_ERROR)) {
$error = $session->get(SecurityContextInterface::AUTHENTICATION_ERROR);
$session->remove(SecurityContextInterface::AUTHENTICATION_ERROR);
} else {
$error = '';
}
// last username entered by the user
$lastUsername = (null === $session) ? '' : $session->get(SecurityContextInterface::LAST_USERNAME);
return $this->render(
'IwSecurityBundle:Security:login.html.twig',
array(
// last username entered by the user
'last_username' => $lastUsername,
'error' => $error,
)
);
}
User entity
class User implements AdvancedUserInterface, \Serializable
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=25, unique=true)
*/
private $username;
/**
* @ORM\Column(type="string", length=60, unique=true)
*/
private $email;
/**
* @ORM\Column(type="string", length=250)
*/
private $password;
/**
* @ORM\Column(type="string", length=250)
*/
private $salt;
/**
* @ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
/**
* @ORM\ManyToMany(targetEntity="UserRoles", inversedBy="users")
*
*/
private $roles;
public function __construct()
{
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
$this->roles = new ArrayCollection();
}
}
User repository
public function loadUserByUsername($username)
{
$q = $this
->createQueryBuilder('u')
->select('u, r')
->leftJoin('u.roles', 'r')
->where('u.username = :username OR u.email = :email')
->setParameter('username', $username)
->setParameter('email', $username)
->getQuery();
try {
$user = $q->getSingleResult();
} catch (NoResultException $e) {
throw new UsernameNotFoundException(sprintf('Unable to find an active admin AcmeUserBundle:User object identified by "%s".', $username), 0, $e);
}
return $user;
}
And the form registration service
public function formRegisterAccount($formData, $role = "ROLE_USER") {
$newUser = new Entity\User;
$userRoles = $this->em->getRepository('IwSecurityBundle:UserRoles')->findOneBy(array('role' => $role));
// $encoder = $this -> factory -> getEncoder($newUser);
if (count($this->getUserByUsernameOrEmail($formData->getUsername(), $formData->getEmail())) > 0) {
return;
}
//Password encoding
$encoder = $this->factory->getEncoder($newUser);
$newUser->setUserName($formData->getUsername());
$newUser->setEmail($formData->getEmail());
$newUser->setPassword($encoder->encodePassword($formData->getPassword(), $formData->getSalt()));
// $newUser->setIsActive(FALSE);
$newUser->addRole($userRoles);
$this->em->persist($newUser);
$this->em->flush();
return $newUser;
}
What am i doing wrong?
Got it solved! I've used the encoderFactory in my service and registration is now working
service.yml
security_service:
class: Iwooli\SecurityBundle\Service\SecurityService
arguments: [@security.encoder_factory]
SecurityService
use Symfony\Component\Security\Core\Encoder\EncoderFactory;
class SecurityService {
private $factory;
public function __construct(EncoderFactory $encoderFactory) {
$this->factory = $encoderFactory;
}
public function formRegisterAccount($formData, $role = "ROLE_USER") {
$newUser = new Entity\User;
//Password encoding
$encoder = $this->factory->getEncoder($newUser);
$password = $encoder->encodePassword($formData->getPassword(), $newUser->getSalt());
...
$newUser->setPassword($password);
...
return $newUser;
}
}
Hope that helps
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.