Symfony3 Security - Load User from database does not work - symfony

I have a Invalid credentials error when I'm trying to load my user form the database.
Here is my security.yml
security:
providers:
database:
entity: { class: AppBundle\Entity\User, property: username }
encoders:
AppBundle\Entity\User: plaintext
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
# pattern: ^/
form_login:
login_path: /login
check_path: /login_check
# default_target_path: /admin
provider: database
logout:
path: /logout
target: /login
My User Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
*/
class User implements UserInterface
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", unique=true)
*/
private $username;
/**
* #ORM\Column(type="string")
*/
private $password;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* Returns the password used to authenticate the user.
*
* This should be the encoded password. On authentication, a plain-text
* password will be salted, encoded, and then compared to this value.
*
* #return string The password
*/
public function getPassword()
{
return $this->password;
}
/**
* Set password
*
* #param string $password
*
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Returns the salt that was originally used to encode the password.
*
* This can return null if the password was not encoded using a salt.
*
* #return string|null The salt
*/
public function getSalt()
{
}
/**
* Returns the username used to authenticate the user.
*
* #return string The username
*/
public function getUsername()
{
return $this->getUsername();
}
/**
* Set username
*
* #param string $username
*
* #return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
// TODO: Implement eraseCredentials() method.
}
/**
* Returns the roles granted to the user.
*
* <code>
* public function getRoles()
* {
* return array('ROLE_USER');
* }
* </code>
*
* Alternatively, the roles might be stored on a ``roles`` property,
* and populated in any number of different ways when the user object
* is created.
*
* #return (Role|string)[] The user roles
*/
public function getRoles()
{
// TODO: Implement getRoles() method.
}
}
My Controllers:
/**
* #Route("/login", name="login")
*/
public function loginAction(Request $request)
{
$authenticationUtils = $this->get('security.authentication_utils');
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
$form = $this->createForm(LoginType::class, array(
'_username' => $lastUsername,
));
return $this->render(':back/security:login.html.twig', array(
'error' => $error,
'form' => $form->createView(),
));
}
/**
* #Route("/login_check", name="login_check")
*/
public function loginCheckAction(){}
I don't understand why it does not work. I have tried to follow the documentation and make it very simple.
The user is in my database and the password is plaintext.
What did I do wrong?

Related

Cannot refresh token because user has changed Syfmony 4 - EquatableInterface problem

I have made login form with Security Guide. When I try to login I have logs like below:
2019-06-10 10:16:56] security.INFO: User has been authenticated successfully. {"username":"user#example.com"} []
[2019-06-10 10:16:56] security.DEBUG: Stored the security token in the session. {"key":"_security_main"} []
[2019-06-10 10:16:56] request.INFO: Matched route "app_user_dashboard". {"route":"app_user_dashboard","route_parameters":{"_route":"app_user_dashboard","_controller":"App\\Controller\\User\\UserController::dashboard"},"request_uri":"https://127.0.0.1:8001/app/dashboard","method":"GET"} []
[2019-06-10 10:16:56] security.DEBUG: Read existing security token from the session. {"key":"_security_main","token_class":"Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken"} []
[2019-06-10 10:16:57] doctrine.DEBUG: SELECT t0.id AS id_1, t0.password AS password_2, t0.email AS email_3, t0.first_name AS first_name_4, t0.last_name AS last_name_5, t0.username AS username_6, t0.referral_code AS referral_code_7, t0.referred_by_code AS referred_by_code_8, t0.roles AS roles_9, t0.active_to AS active_to_10, t0.created_at AS created_at_11, t0.updated_at AS updated_at_12 FROM users t0 WHERE t0.id = ? [15] []
[2019-06-10 10:16:57] security.DEBUG: Cannot refresh token because user has changed. {"username":"user#example.com","provider":"Symfony\\Bridge\\Doctrine\\Security\\User\\EntityUserProvider"} []
[2019-06-10 10:16:57] security.DEBUG: Token was deauthenticated after trying to refresh it. [] []
and also I use EquatableInterface. My User.php code:
namespace App\Entity\User;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use Exception;
use Serializable;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\EquatableInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Class User
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="App\Repository\User\UserRepository")
* #ORM\HasLifecycleCallbacks
*
* #ORM\Entity
* #UniqueEntity(fields="username", message="username taken")
* #UniqueEntity(fields="email", message="email taken")
*/
class User implements UserInterface, Serializable, EquatableInterface
{
/**
* #var int
*
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(type="string", length=256)
*/
private $password;
/**
* #var string
*
* #ORM\Column(type="string", length=64, unique=true)
*/
private $email;
/**
* #var string|null
*
* #ORM\Column(type="string", length=64, nullable=true)
*/
private $firstName;
/**
* #var string|null
*
* #ORM\Column(type="string", length=64, nullable=true)
*/
private $lastName;
/**
* #var string
*
* #ORM\Column(type="string", length=64, unique=true)
*/
private $username;
/**
* #var string
*
* #ORM\Column(type="string", length=64, unique=true)
*/
private $referralCode;
/**
* #var string|null
*
* #ORM\Column(type="string", length=64, nullable=true)
*/
private $referredByCode;
/**
* #var array
*
* #ORM\Column(type="array", length=64)
*/
private $roles;
/**
* #var DateTime
*
* #ORM\Column(type="datetime")
*/
private $activeTo;
/**
* #var DateTime
*
* #ORM\Column(type="datetime")
*/
private $createdAt;
/**
* #var DateTime
*
* #ORM\Column(type="datetime", nullable=true)
*/
private $updatedAt;
/**
* User constructor.
*
* #throws Exception
*/
public function __construct()
{
$this->createdAt = new DateTime();
$this->updatedAt = new DateTime();
$this->activeTo = new DateTime('now + 14 days');
$this->referralCode = substr(hash('sha256', uniqid()), 0, 5);
}
/**
* #return string
*/
public function __toString()
{
return $this->getUsername();
}
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #param string $username
*/
public function setUsername(string $username): void
{
$this->username = $username;
}
/**
* #return string
*/
public function getUsername(): ?string
{
return $this->username;
}
/**
* #return null|string
*/
public function getSalt(): ?string
{
// you *may* need a real salt depending on your encoder
// see section on salt below
return null;
}
/**
* #return string
*/
public function getPassword(): ?string
{
return $this->password;
}
/**
* #param string $password
*/
public function setPassword(string $password)
{
$this->password = $password;
}
/**
* #return array
*/
public function getRoles(): array
{
// return $this->roles;
return ['ROLE_USER', 'ROLE_API_USER'];
}
/**
*
*/
public function eraseCredentials()
{
}
/**
* #see Serializable::serialize()
*/
public function serialize()
{
return serialize(array($this->id, $this->email));
}
/**
* #see Serializable::unserialize()
*
* #param $serialized
*/
public function unserialize($serialized)
{
list ($this->id, $this->email) = unserialize($serialized, array('allowed_classes' => false));
}
/**
* #return string
*/
public function getEmail(): ?string
{
return $this->email;
}
/**
* #param string $email
*/
public function setEmail(string $email): void
{
$this->email = $email;
}
/**
* #return DateTime
*/
public function getCreatedAt(): DateTime
{
return $this->createdAt;
}
/**
* #ORM\PrePersist
*
* #throws Exception
*/
public function setCreatedAt(): void
{
$this->createdAt = new DateTime();
}
/**
* #return DateTime
*/
public function getUpdatedAt(): DateTime
{
return $this->updatedAt;
}
/**
* #ORM\PreUpdate
*
* #throws Exception
*/
public function setUpdatedAt(): void
{
$this->updatedAt = new DateTime();
}
/**
* #return DateTime
*/
public function getActiveTo(): DateTime
{
return $this->activeTo;
}
/**
* #param DateTime $activeTo
*/
public function setActiveTo(DateTime $activeTo): void
{
$this->activeTo = $activeTo;
}
/**
* #return string
*/
public function getReferralCode(): string
{
return $this->referralCode;
}
/**
* #param string $referralCode
*/
public function setReferralCode(string $referralCode): void
{
$this->referralCode = $referralCode;
}
/**
* #return string|null
*/
public function getReferredByCode():? string
{
return $this->referredByCode;
}
/**
* #param string|null $referredByCode
*/
public function setReferredByCode(?string $referredByCode): void
{
$this->referredByCode = $referredByCode;
}
/**
* #return string|null
*/
public function getFirstName(): ?string
{
return $this->firstName;
}
/**
* #param string|null $firstName
*/
public function setFirstName(?string $firstName): void
{
$this->firstName = $firstName;
}
/**
* #return string|null
*/
public function getLastName(): ?string
{
return $this->lastName;
}
/**
* #param string|null $lastName
*/
public function setLastName(?string $lastName): void
{
$this->lastName = $lastName;
}
/**
* #param array $roles
*/
public function setRoles(array $roles): void
{
$this->roles = $roles;
}
/**
* The equality comparison should neither be done by referential equality
* nor by comparing identities (i.e. getId() === getId()).
*
* However, you do not need to compare every attribute, but only those that
* are relevant for assessing whether re-authentication is required.
*
* #param UserInterface $user
*
* #return bool
*/
public function isEqualTo(UserInterface $user)
{
if ($this->username !== $user->getUsername()) {
return false;
}
return true;
}
}
and security.yaml
encoders:
App\Entity\User\User:
algorithm: auto
providers:
user_provider:
entity:
class: App\Entity\User\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
http_basic: ~
anonymous: true
# logout_on_user_change: true
provider: user_provider
form_login:
login_path: app_user_login
check_path: app_user_login
default_target_path: app_user_dashboard
csrf_token_generator: security.csrf.token_manager
logout:
path: /app/logout
target: /app/login
# activate different ways to authenticate
# http_basic: true
# https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
# form_login: true
# https://symfony.com/doc/current/security/form_login_setup.html
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/app/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/app/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/app, roles: IS_AUTHENTICATED_FULLY }
I have red this post: Token was deauthenticated after trying to refresh it and that solution does not work for me. Any ideas?
You've got 2 options here:
Make your firewall stateless or
update your serialization in you User
I'm referring to https://symfony.com/doc/current/security/user_provider.html#understanding-how-users-are-refreshed-from-the-session btw, as I had the same issue.
First solution:
firewalls:
# ...
main:
http_basic: ~
anonymous: true
stateless: true
This should make Symfony ignore your serialization and just reload the whole entity from database.
Second solution:
class User implements UserInterface, Serializable, EquatableInterface
{
public function serialize()
{
return serialize(array(
$this->id,
$this->password,
$this->email,
$this->username,
$this->activeTo,
));
}
public function unserialize($serialized)
{
list (
$this->id,
$this->password,
$this->email,
$this->username,
$this->activeTo,
) = unserialize($serialized, array('allowed_classes' => false));
}
}
You should keep any information that Symfony might need in any of your user_checker classes (or the default ones).

The token storage contains no authentication token

I'm stack heeeere in security, help me please!!
I got this error 2 days ago and couldn't solve it : "The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL." My login in the index page, and the login and login_check are in the same function (indexAction).This is my security.yml file, my controller, and my entity "user" :
# you can read more about security in the related section of the documentation
# http://symfony.com/doc/current/book/security.html
security:
# http://symfony.com/doc/current/book/security.html#encoding-the-user-s-password
encoders:
#Symfony\Component\Security\Core\User\User: plaintext
CNAM\CMSBundle\Entity\user: bcrypt
# http://symfony.com/doc/current/book/security.html#hierarchical-roles
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
providers:
in_memory:
memory:
users:
user: { password: userpass, roles: [ 'ROLE_USER' ] }
admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
database:
entity:
class: CNAM\CMSBundle\Entity\user
property: username
# the main part of the security, where you can set up firewalls
# for specific sections of your app
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin_area:
pattern: ^/admin
form_login:
check_path: _default_index
login_path: _default_index
access_control:
#- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY}
- { path: ^/admin, roles: ROLE_ADMIN}
<?php
namespace CNAM\CMSBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
use CNAM\CMSBundle\Entity\user;
use CNAM\CMSBundle\Entity\userprof;
use CNAM\CMSBundle\Entity\profil;
use CNAM\CMSBundle\Entity\privilege;
use Symfony\Component\BrowserKit\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Security\Core\Security;
class DefaultController extends Controller
{
/**
* #Route("/")
* #Template()
*/
public function indexAction(Request $request)
{
$user = new user();
$form = $this->createFormBuilder($user)
->add('id', 'text',array('attr'=>array('name'=>'login_user','required'=>'required',
'maxlength'=>'255','placeholder'=>'Votre matricule','id'=>'login_user')))
->add('password', 'password',array('attr'=>array('name'=>'login_password','required'=>'required',
'maxlength'=>'20','placeholder'=>'Mot de passe','id'=>'login_password')))
->add('Connexion', 'submit',array('attr'=>array('class'=>'btn btn-primary btn-block rounded_btn','id'=>'login_btn',
'style'=>"width:8vw;height:5vh;padding:0px 0px; position:relative;left:5vmin;top:1vmin;font-size:2vmin;")))
->getForm();
$form->handleRequest($request);
//$b_search=$this->get('session')->get('search');
$id = $request->request->get('id');
$session = $request->getSession();
if ($form->isValid()) {
$data = $form->getData();
$repository = $this
->getDoctrine()
->getManager()
->getRepository("CNAMCMSBundle:user");
$rep = $this
->getDoctrine()
->getManager()
->getRepository("CNAMCMSBundle:userprof");
$search = $repository->find($data);
$p_search=$rep->find($data);
$helper = $this->get('security.authentication_utils');
if (!$search) {
//throw $this->createNotFoundException('Utilisateur introuvable!');
}
else {
//$session=$this->get("session");
//$session->start();
// $session->set('search', $search);
$user->setEtat(1);
$em = $this->getDoctrine()->getManager();
$user=$em->merge($user);
$em->flush();
$id_prof=$p_search->getIdProfil();
switch ($id_prof)
{
case 1: return $this->redirect($this->generateUrl('cnam_cms_default_webmaster'),301);break;
case 2: $user->setRole("ROLE_ADMIN");$em = $this->getDoctrine()->getManager();$user=$em->merge($user);
$em->flush();return $this->redirect($this->generateUrl('cnam_cms_default_admin'),301);break;
case 3: return $this->redirect($this->generateUrl('cnam_cms_default_sup_med'),301);break;
case 4: return $this->redirect($this->generateUrl('cnam_cms_default_med'),301);break;
case 5: return $this->redirect($this->generateUrl('cnam_cms_default_gest_mp'),301);break;
}
}
//return $this->render('CNAMCMSBundle:Default:profile.html.twig', array(
//'search' => $search,
//'b_search'=>$b_search
// ));
}
return array('form'=>$form->createView());
}
/**
* #Route("/admin")
* #Template()
*/
public function adminAction()
{
return $this->render('CNAMCMSBundle:Default:admin.html.twig', array());
}
/**
* #Route("/admin/gestEtat",name="gestEtat")
* #Template()
*/
public function gestEtatAction()
{
return $this->render('CNAMCMSBundle:Default:gestEtat.html.twig', array());
}
}
<?php
namespace CNAM\CMSBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* user
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class user implements UserInterface
{
/**
* #var integer
*#Assert\NotBlank()
* #ORM\Column(name="id", type="integer")
* #ORM\Id
*/
private $id;
/**
* #var string
*#Assert\NotBlank()
* #ORM\Column(name="password", type="string", length=40)
*/
private $password;
/*
* #ORM\ManyToOne(targetEntity="profil" , inversedBy="users")
* #ORM\JoinColumn(name="id_profil", referencedColumnName="id_profil")
*/
private $profil;
public function __construct()
{
$this->profil = new ArrayCollection();
}
/**
* #var boolean
*
* #ORM\Column(name="etat", type="boolean")
*/
private $etat;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set id
*
* #param integer $id
* #return user
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Set password
*
* #param string $password
* #return user
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set etat
*
* #param boolean $etat
* #return user
*/
public function setEtat($etat)
{
$this->etat = $etat;
return $this;
}
/**
* Get etat
*
* #return boolean
*/
public function getEtat()
{
return $this->etat;
}
/**
* Get profil
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProfil()
{
return $this->profil;
}
/**
* Add profil
*
* #param \CNAM\CMSBundle\Entity\user $profil
* #return user
*/
public function addProfil(\CNAM\CMSBundle\Entity\profil $profil)
{
$this->profil[] = $profil;
return $this;
}
/**
* Remove profil
*
* #param \CNAM\CMSBundle\Entity\profil $profil
*/
public function removeProfil(\CNAM\CMSBundle\Entity\profil $profil)
{
$this->profil->removeElement($profil);
}
public function getUsername()
{
return $this->id;
}
public function getRoles()
{
return array('ROLE_USER');
}
public function getSalt()
{
return null;
}
public function eraseCredentials()
{
}
public function equals(UserInterface $user)
{
return $user->getId() == $this->getId();
}
}

symfony doctrine authentication bad credentials

I'm trying to follow the documentation but can't get it to work. I keep getting "Bad credentials" when trying to use the login form.
Here is my security.yml file
security:
encoders:
MyCompany\MyPoroject\UserBundle\Entity\User:
algorithm: sha1
encode_as_base64: false
iterations: 1
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
administrators:
entity: { class: MyCompanyMyProjectUserBundle:User, property: username }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: login
check_path: login_check
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
This is the code i've used to create some dummy users
$factory = $this->get('security.encoder_factory');
$user = new User;
$encoder = $factory->getEncoder($user);
$password = $encoder->encodePassword('testing', $user->getSalt());
$user->setPassword($password)
->setEmail('test#gmail.com')
->setUsername('testing');
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
Here is my User class
class User implements UserInterface, \Serializable
{
private $id;
private $username;
private $salt;
private $password;
private $email;
private $isActive;
public function __construct()
{
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}
/**
* Returns the roles granted to the user.
*
* <code>
* public function getRoles()
* {
* return array('ROLE_USER');
* }
* </code>
*
* Alternatively, the roles might be stored on a ``roles`` property,
* and populated in any number of different ways when the user object
* is created.
*
* #return Role[] The user roles
*/
public function getRoles()
{
return ['ROLE_USER'];
}
/**
* Returns the password used to authenticate the user.
*
* This should be the encoded password. On authentication, a plain-text
* password will be salted, encoded, and then compared to this value.
*
* #return string The password
*/
public function getPassword()
{
$this->password;
}
/**
* Returns the salt that was originally used to encode the password.
*
* This can return null if the password was not encoded using a salt.
*
* #return string|null The salt
*/
public function getSalt()
{
$this->salt;
}
/**
* Returns the username used to authenticate the user.
*
* #return string The username
*/
public function getUsername()
{
return $this->username;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
* #return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Set salt
*
* #param string $salt
* #return User
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Set password
*
* #param string $password
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Set email
*
* #param string $email
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set is_active
*
* #param boolean $isActive
* #return User
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get is_active
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* (PHP 5 >= 5.1.0)<br/>
* String representation of object
* #link http://php.net/manual/en/serializable.serialize.php
* #return string the string representation of the object or null
*/
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->salt,
$this->password,
));
}
/**
* (PHP 5 >= 5.1.0)<br/>
* Constructs the object
* #link http://php.net/manual/en/serializable.unserialize.php
* #param string $serialized <p>
* The string representation of the object.
* </p>
* #return void
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->salt,
$this->password,
) = unserialize($serialized);
}
/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
}
}
My Security controller
class SecurityController extends Controller
{
public function loginAction(Request $request)
{
$session = $request->getSession();
// get the login error if there is one
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(
SecurityContext::AUTHENTICATION_ERROR
);
} else {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render(
'MyCompanyMyProjectUserBundle:Security:login.html.twig',
array(
// last username entered by the user
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
)
);
}
public function adminAction()
{
return $this->render('MyCompanyMyProjectUserBundle:Security:admin.html.twig');
}
}
This is the record in the database i'm attempting to login with using testing as both the username and password.
id: 3
username(25): testing
salt(32): 87a449194ebfe80bfa9f59da53dab0ea
password(64): dc724af18fbdd4e59189f5fe768a5f8311527050
email(60): test#gmail.com
Probably you missed return statement in getSalt() and getPassword() methods

Bad credentials with Fosuser symfony2

I'm trying since 3 hours to install and configure FOSuser, which many developpers adviced me to use it.I wanted actually to make a normal login form without to use FOS but I had a lot of problems.I followed all steps in the documentation. the installation was ok , the configuration also but everytime when I try to log in , it shows "Bad credentials".So i find somehow this command that I executed :php app/console fos:user:create i give name-email-password. it work somehow but only with what i write, I mean when I register user in my registration form and try to log in it shows "Bad credentials".I hope that I was clear else please tell me what do you need to know
Here are my Users.php where i have all my users info to login...
namespace test\indexBundle\Document;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
*
* #MongoDB\Document
*/
class Users extends BaseUser
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
*/
protected $userId;
/**
* #MongoDB\String
*/
protected $userEmail;
/**
* #MongoDB\String
*/
protected $userPassword;
/**
* #MongoDB\String
*/
protected $salt;
/**
* #MongoDB\Int
*/
protected $isActive;
public function __construct()
{
parent::__construct();
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}
/**
* Set id
*
* #param id $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Get id
*
* #return id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set userId
*
* #param string $userId
*/
public function setUserId()
{
$this->userId = $this->salt;
}
/**
* Get userId
*
* #return string $userId
*/
public function getUserId()
{
return $this->userId;
}
/**
* Set userName
*
* #param string $userName
*/
public function setUserName($userName)
{
$this->userName = $userName;
}
/**
* Get userName
*
* #return string $userName
*/
public function getUserName()
{
return $this->username;
}
/**
* Set userEmail
*
* #param string $userEmail
*/
public function setUserEmail($userEmail)
{
$this->userEmail = $userEmail;
}
/**
* Get userEmail
*
* #return string $userEmail
*/
public function getUserEmail()
{
return $this->userEmail;
}
/**
* Set userPassword
*
* #param string $userPassword
*/
public function setPassword($userPassword)
{
$this->userPassword = $userPassword;
}
/**
* Get userPassword
*
* #return string $userPassword
*/
public function getPassword()
{
return $this->userPassword;
}
/**
* #inheritDoc
*/
public function getSalt()
{
return '';
}
/**
* #inheritDoc
*/
public function getRoles()
{
return array('ROLE_USER');
}
/**
* #inheritDoc
*/
public function eraseCredentials()
{
}
/**
* #see \Serializable::serialize()
*/
public function serialize()
{
return serialize(array(
$this->id
));
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id
) = unserialize($serialized);
}
}
and here my security.yml:
jms_security_extra:
secure_all_services: false
expressions: true
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
test\indexBundle\Document\Users:
algorithm: sha1
encode_as_base64: false
iterations: 1
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
anonymous: true
form_login:
check_path: /login_check
login_path: /login
provider: fos_userbundle
post_only: true
use_forward: false
username_parameter: email
password_parameter: password
failure_path: null
failure_forward: false
target_path_parameter: redirect_url
logout:
path: /logout
target: /blog
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
and login function:
public function loginAction()
{
$request = $this->getRequest();
$session = $request->getSession();
if ($this->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY'))
{
return $this->redirect($this->generateUrl('index_homepage'));
}
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR))
{
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
}
else
{
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render('indexBundle:index:logIn.html.twig', array(
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
));
}
I might be wrong but I think FOSUserBundle requires a user to be activated after it's been created if you use the form registration, it's send out and email with a link I believe. I think you can use app/console fos:user:activate to activate if there is no email.

Symfony2 authentication/login using email instead of username

I've been trying to create a login form today using Symfony2 where a user can login using their email address and password. I've had lot's of problems and in the end realised it will only work if I have a $username property in my AdminUser entity class. I've tried to use email instead of username where possible so can someone please explain why $username is required or where I have gone wrong? Also, in my login.html.twig file I am still using _username rather than _email if that makes any difference? My code is below (I've removed some getters and setters which aren't applicable):
AdminUser Entity:
namespace XXX\WebsiteBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* AdminUser
*
* #ORM\Table(name="admin_user",indexes={#ORM\Index(name="indexes", columns={"deleted"})})
* #ORM\Entity
* #ORM\HasLifecycleCallbacks()
*/
class AdminUser implements UserInterface
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=45)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=45, unique=true)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="salt", type="string", length=255)
*/
private $salt;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $password;
/**
* #var integer
*
* #ORM\Column(name="enabled", type="integer", options={"default" = 0})
*/
private $enabled;
/**
* #var string[] $roles
*
* #ORM\Column(name="roles", type="array")
*/
private $roles = array();
private $username;
/**
* Gets the username.
*
* #return string The username.
*/
public function getUsername()
{
return $this->email;
}
/**
* Erases the user credentials.
*/
public function eraseCredentials()
{
}
/**
* Returns the roles granted to the user.
*
* <code>
* public function getRoles()
* {
* return array('ROLE_USER');
* }
* </code>
*
* Alternatively, the roles might be stored on a ``roles`` property,
* and populated in any number of different ways when the user object
* is created.
*
* #return Role[] The user roles
*/
public function getRoles() {
return $this -> roles;
}
/**
* Set the roles of the user
*
* #var string[] $roles
*
* #return \XXX\WebsiteBundle\Entity\User this
*/
public function setRoles(array $roles) {
$this -> roles = $roles;
return $this;
}
}
My security.yml file is:
jms_security_extra:
secure_all_services: false
expressions: true
security:
encoders:
XXX\WebsiteBundle\Entity\AdminUser: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
main_provider:
entity: { class: XXX\WebsiteBundle\Entity\AdminUser, property: email }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin_firewall:
pattern: ^/admin.*
anonymous: ~
form_login:
login_path: /admin/login
check_path: /admin/login_check
access_control:
- { path: ^/admin/login.*, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin.*, roles: ROLE_ADMIN }
I guess you should change property with email and also you can change the _username parameter with anything you want by:
entity:
entity:
class: SecurityBundle:User
property: username
and
firewalls
form_login:
username_parameter: _username
may be you should have a look at security configuration document
firewalls:
main:
form_login:
username_parameter: _email
All of your code is correct you only need to make a little change in the security.yml file. just add the username_parameter.
This is kinda hackish, but you could remove the username field from your registration forms, and in your user entity, do this:
public function setEmail($email)
{
$this->email = $email;
$this->username = $email;
}
Try and use FOSUserBundle.
It has a default feature for users to be able to login with their username or email fields.

Resources