Token was deauthenticated after trying to refresh it - php

I updated my Symfony environment form 3.3 to 4.0. After the update I have problems with the login (user provided by database). When I submit the login form, I just got right back to the login form without any error message. When I use invalid credentials, I got the corresponding error message. Here is the log after trying to login. The login with the "in_memory" user provider is working. Do you need more information?
[2017-12-06 13:57:05] security.INFO: User has been authenticated successfully. {"username":"***"} []
[2017-12-06 14:22:39] doctrine.DEBUG: "START TRANSACTION" [] []
[2017-12-06 13:57:05] security.DEBUG: Read existing security token from the session. {"key":"_security_secured_area","token_class":"Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken"} []
[2017-12-06 13:57:05] doctrine.DEBUG: SELECT t0.username AS username_1, t0.password AS password_2, t0.email AS email_3, t0.email_new AS email_new_4, t0.first_name AS first_name_5, t0.last_name AS last_name_6, t0.is_active AS is_active_7, t0.email_confirmed AS email_confirmed_8, t0.shibboleth_state AS shibboleth_state_9, t0.shibboleth_hash AS shibboleth_hash_10, t0.shibboleth_persistent_id AS shibboleth_persistent_id_11, t0.confirmation_email_send AS confirmation_email_send_12, t0.last_login AS last_login_13, t0.expires AS expires_14, t0.session_id AS session_id_15, t0.id AS id_16, t0.hidden AS hidden_17, t0.deleted AS deleted_18, t0.created AS created_19, t0.modified AS modified_20, t0.sorting AS sorting_21, t0.salutation_id AS salutation_id_22, t0.creator_id AS creator_id_23, t0.modifier_id AS modifier_id_24 FROM User t0 WHERE t0.id = ? AND ((t0.deleted = 0)) [2] []
[2017-12-06 13:57:05] security.DEBUG: Token was deauthenticated after trying to refresh it. {"username":"user","provider":"Symfony\\Component\\Security\\Core\\User\\ChainUserProvider"} []
[2017-12-06 13:57:05] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2017-12-06 13:57:05] security.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at /vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AccessListener.php:68)"} []
[2017-12-06 13:57:05] security.DEBUG: Calling Authentication entry point. [] []
Entity\User:
class User extends EntitySuperclass implements AdvancedUserInterface, \Serializable
{
/**
* #ORM\Column(type="string")
*/
private $username;
/**
*
* #Assert\Length(max=4096,groups={"account_complete","account_password","user"})
* #Assert\Length(min = 8,groups={"account_complete","account_password","user"}, minMessage="user.password_length")
*/
private $plainPassword;
/**
* The below length depends on the "algorithm" you use for encoding
* the password, but this works well with bcrypt.
*
* #ORM\Column(type="string", length=64)
*/
private $password;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank(groups={"account_register","user"})
* #Assert\Email(
* groups = {"account_register", "account","user"},
* strict = true,
* checkMX = true
* )
*/
private $email;
/**
* #ORM\Column(type="string", length=255)
*/
private $emailNew = '';
/**
* #ORM\ManyToOne(targetEntity="Salutation")
*
*/
private $salutation;
/**
* #ORM\Column(type="string")
* #Assert\NotBlank(groups={"account_complete","user"})
* #Assert\Regex(pattern = "/^[a-zA-ZäöüÄÖÜß0-9 ]+$/",groups={"account_complete","user"}, message="user.first_name.regex")
*/
private $firstName;
/**
* #ORM\Column(type="string")
* #Assert\NotBlank(groups={"account_complete","user"})
* #Assert\Regex(pattern = "/^[a-zA-ZäöüÄÖÜß0-9 ]+$/",groups={"account_complete","user"}, message="user.last_name.regex")
*/
private $lastName;
/**
* #ORM\Column(name="is_active", type="boolean")
*/
private $isActive = false;
/**
* #ORM\Column(name="email_confirmed", type="boolean")
*/
private $emailConfirmed = false;
/**
* #ORM\Column(type="integer")
*/
private $shibbolethState = 0;
/**
* #ORM\Column(type="string")
*/
private $shibbolethHash = '';
/**
* #ORM\Column(type="string")
*/
private $shibbolethPersistentId = '';
/**
* #ORM\ManyToMany(targetEntity="UserGroup")
* #ORM\JoinTable(name="User_UserGroup",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
private $userGroups;
/**
* #ORM\Column(type="integer")
*/
private $confirmationEmailSend;
/**
* #ORM\Column(type="integer")
*/
private $lastLogin = 0;
/**
* #ORM\Column(type="integer")
*/
protected $expires = 0;
/**
* #ORM\Column(type="string", length=255)
*/
private $sessionId = '';
/**
* #ORM\ManyToMany(targetEntity="BankDetails", cascade={"persist"})
* #ORM\JoinTable(name="User_BankDetails",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="bank_details_id", referencedColumnName="id")}
* )
* #Assert\Valid
*/
private $bankDetails;
/**
* #ORM\ManyToMany(targetEntity="Address", cascade={"persist"})
* #ORM\JoinTable(name="User_BillingAddress",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="billing_address_id", referencedColumnName="id")}
* )
* #Assert\Count(
* min = 1,
* minMessage = "user.billing_addresses.min",
* )
* #Assert\Valid
*/
private $billingAddresses;
public function __construct()
{
parent::__construct();
$this->isActive = true;
$this->confirmationEmailSend = 0;
$this->userGroups = new ArrayCollection();
$this->bankDetails = new ArrayCollection();
$this->billingAddresses = new ArrayCollection();
// may not be needed, see section on salt below
// $this->salt = md5(uniqid(null, true));
}
/**
* #ORM\PrePersist
*/
public function prePersist()
{
$currentTimestamp = time();
if($this->getConfirmationEmailSend() == NULL)
$this->setConfirmationEmailSend(0);
}
public function getUsername()
{
//return $this->username;
return $this->email;
}
public function getSalt()
{
// The bcrypt algorithm doesn't require a separate salt.
return null;
}
public function getPassword()
{
return $this->password;
}
public function getRoles()
{
$roles = array();
$userGroups = $this->getUserGroups();
if(!empty($userGroups)) {
foreach($userGroups as $userGroup) {
$role = $userGroup->getRole();
$roles[] = 'ROLE_'.strtoupper($role);
}
}
return $roles;
}
public function isGranted($role)
{
return in_array($role, $this->getRoles());
}
public function eraseCredentials()
{
}
public function isAccountNonExpired()
{
return true;
}
public function isAccountNonLocked()
{
return true;
}
public function isCredentialsNonExpired()
{
return true;
}
public function isEnabled()
{
return $this->isActive;
}
/** #see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
$this->isActive,
// see section on salt below
// $this->salt,
));
}
/** #see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
$this->isActive,
// see section on salt below
// $this->salt
) = unserialize($serialized);
}
/**
* Set username
*
* #param string $username
*
* #return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
public function getPlainPassword()
{
return $this->plainPassword;
}
public function setPlainPassword($password)
{
$this->plainPassword = $password;
}
/**
* 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;
$this->setUsername($email);
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set isActive
*
* #param boolean $isActive
*
* #return User
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get isActive
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* Add userGroup
*
* #param \AppBundle\Entity\UserGroup $userGroup
*
* #return User
*/
public function addUserGroup(\AppBundle\Entity\UserGroup $userGroup)
{
$this->userGroups[] = $userGroup;
return $this;
}
/**
* Remove userGroup
*
* #param \AppBundle\Entity\UserGroup $userGroup
*/
public function removeUserGroup(\AppBundle\Entity\UserGroup $userGroup)
{
$this->userGroups->removeElement($userGroup);
}
/**
* Get userGroups
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getUserGroups()
{
return $this->userGroups;
}
/**
* Set shibbolethPersistentId
*
* #param string $shibbolethPersistentId
*
* #return User
*/
public function setShibbolethPersistentId($shibbolethPersistentId)
{
$this->shibbolethPersistentId = $shibbolethPersistentId;
return $this;
}
/**
* Get shibbolethPersistentId
*
* #return string
*/
public function getShibbolethPersistentId()
{
return $this->shibbolethPersistentId;
}
/**
* Set firstName
*
* #param string $firstName
*
* #return User
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
return $this;
}
/**
* Get firstName
*
* #return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Set lastName
*
* #param string $lastName
*
* #return User
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
return $this;
}
/**
* Get lastName
*
* #return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Set emailConfirmed
*
* #param boolean $emailConfirmed
*
* #return User
*/
public function setEmailConfirmed($emailConfirmed)
{
$this->emailConfirmed = $emailConfirmed;
return $this;
}
/**
* Get emailConfirmed
*
* #return boolean
*/
public function getEmailConfirmed()
{
return $this->emailConfirmed;
}
public function removeAllUserGroups() {
$userGroups = $this->getUserGroups();
foreach($userGroups as $userGroup) {
$this->removeUserGroup($userGroup);
}
}
public function hasUserGroup($userGroupId) {
foreach($this->getUserGroups() as $userGroup) {
if($userGroup->getId() == $userGroupId)
return true;
}
return false;
}
/**
* Set lastLogin
*
* #param integer $lastLogin
*
* #return User
*/
public function setLastLogin($lastLogin)
{
$this->lastLogin = $lastLogin;
return $this;
}
/**
* Get lastLogin
*
* #return integer
*/
public function getLastLogin()
{
return $this->lastLogin;
}
/**
* Set confirmationEmailSend
*
* #param integer $confirmationEmailSend
*
* #return User
*/
public function setConfirmationEmailSend($confirmationEmailSend)
{
$this->confirmationEmailSend = $confirmationEmailSend;
return $this;
}
/**
* Get confirmationEmailSend
*
* #return integer
*/
public function getConfirmationEmailSend()
{
return $this->confirmationEmailSend;
}
/**
* Set validTill
*
* #param integer $validTill
*
* #return User
*/
public function setValidTill($validTill)
{
$this->validTill = $validTill;
return $this;
}
/**
* Get validTill
*
* #return integer
*/
public function getValidTill()
{
return $this->validTill;
}
/**
* Set shibbolethValid
*
* #param integer $shibbolethValid
*
* #return User
*/
public function setShibbolethValid($shibbolethValid)
{
$this->shibbolethValid = $shibbolethValid;
return $this;
}
/**
* Get shibbolethValid
*
* #return integer
*/
public function getShibbolethValid()
{
return $this->shibbolethValid;
}
/**
* Set shibbolethHash
*
* #param string $shibbolethHash
*
* #return User
*/
public function setShibbolethHash($shibbolethHash)
{
$this->shibbolethHash = $shibbolethHash;
return $this;
}
/**
* Get shibbolethHash
*
* #return string
*/
public function getShibbolethHash()
{
return $this->shibbolethHash;
}
/**
* Set shibbolethState
*
* #param integer $shibbolethState
*
* #return User
*/
public function setShibbolethState($shibbolethState)
{
$this->shibbolethState = $shibbolethState;
return $this;
}
/**
* Get shibbolethState
*
* #return integer
*/
public function getShibbolethState()
{
return $this->shibbolethState;
}
/**
* Set expires
*
* #param integer $expires
*
* #return User
*/
public function setExpires($expires)
{
$this->expires = $expires;
return $this;
}
/**
* Get expires
*
* #return integer
*/
public function getExpires()
{
return $this->expires;
}
/**
* Set emailNew
*
* #param string $emailNew
*
* #return User
*/
public function setEmailNew($emailNew)
{
$this->emailNew = $emailNew;
return $this;
}
/**
* Get emailNew
*
* #return string
*/
public function getEmailNew()
{
return $this->emailNew;
}
/**
* Set passwordHash
*
* #param string $passwordHash
*
* #return User
*/
public function setPasswordHash($passwordHash)
{
$this->passwordHash = $passwordHash;
return $this;
}
/**
* Get passwordHash
*
* #return string
*/
public function getPasswordHash()
{
return $this->passwordHash;
}
/**
* Set sessionId
*
* #param string $sessionId
*
* #return User
*/
public function setSessionId($sessionId)
{
$this->sessionId = $sessionId;
return $this;
}
/**
* Get sessionId
*
* #return string
*/
public function getSessionId()
{
return $this->sessionId;
}
/**
* Set salutation
*
* #param \AppBundle\Entity\Salutation $salutation
*
* #return User
*/
public function setSalutation(\AppBundle\Entity\Salutation $salutation = null)
{
$this->salutation = $salutation;
return $this;
}
/**
* Get salutation
*
* #return \AppBundle\Entity\Salutation
*/
public function getSalutation()
{
return $this->salutation;
}
/**
* Add bankDetail
*
* #param \AppBundle\Entity\BankDetails $bankDetail
*
* #return User
*/
public function addBankDetail(\AppBundle\Entity\BankDetails $bankDetail)
{
$this->bankDetails[] = $bankDetail;
return $this;
}
/**
* Remove bankDetail
*
* #param \AppBundle\Entity\BankDetails $bankDetail
*/
public function removeBankDetail(\AppBundle\Entity\BankDetails $bankDetail)
{
$this->bankDetails->removeElement($bankDetail);
}
/**
* Get bankDetails
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getBankDetails()
{
return $this->bankDetails;
}
/**
* Add billingAddress
*
* #param \AppBundle\Entity\Address $billingAddress
*
* #return User
*/
public function addBillingAddress(\AppBundle\Entity\Address $billingAddress)
{
$this->billingAddresses[] = $billingAddress;
return $this;
}
/**
* Remove billingAddress
*
* #param \AppBundle\Entity\Address $billingAddress
*/
public function removeBillingAddress(\AppBundle\Entity\Address $billingAddress)
{
$this->billingAddresses->removeElement($billingAddress);
}
/**
* Set billingAddresses
*
* #param \AppBundle\Entity\Address $billingAddress
*
* #return User
*
*/
public function setBillingAddresses(\AppBundle\Entity\Address $billingAddress)
{
if($this->billingAddresses !== NULL and $this->billingAddresses->contains($billingAddress)){
return false;
}
$this->addBillingAddress($billingAddress);
return $this;
}
/**
* Set one billingAddresses
*
* #param \AppBundle\Entity\Address $billingAddress
*
* #return User
*
*/
public function setOneBillingAddresses(\AppBundle\Entity\Address $billingAddress)
{
$this->billingAddresses = $billingAddress;
return $this;
}
/**
* Set one billingAddresses
*
* #param \AppBundle\Entity\Address $billingAddress
*
* #return User
*
*/
public function unsetBillingAddresses()
{
$this->billingAddresses = new ArrayCollection();
return $this;
}
/**
* Get billingAddresses
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getBillingAddresses()
{
return $this->billingAddresses;
}
}
config/security.yml
providers:
chain_provider:
chain:
providers: [in_memory, database_user]
in_memory:
memory:
users:
admin:
password: ***
roles: 'ROLE_ADMIN'
database_user:
entity:
class: AppBundle:User
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
# pattern: match to pages
anonymous: ~
pattern: ^/
access_denied_handler: AppBundle\Security\AccessDeniedHandler
provider: chain_provider
form_login:
login_path: /login
check_path: /login_check
default_target_path: account
# Configuring CSRF protection
csrf_parameter: _csrf_security_token
csrf_token_id: a_private_string
success_handler: AppBundle\Handler\LoginSuccessHandler
logout:
path: /logout
target: /login
access_control:
...
role_hierarchy:
...
encoders:
AppBundle\Entity\User:
algorithm: bcrypt
Symfony\Component\Security\Core\User\User:
plaintext

As of Symfony 4.0, logout_on_user_change is set to true. That means a user will be logged out if it has been changed.
You should implement Symfony\Component\Security\Core\User\EquatableInterface and add the isEqualTo method:
class User implements EquatableInterface
{
public function isEqualTo(UserInterface $user)
{
if ($this->password !== $user->getPassword()) {
return false;
}
if ($this->salt !== $user->getSalt()) {
return false;
}
if ($this->username !== $user->getUsername()) {
return false;
}
return true;
}
}
Changelog
https://github.com/symfony/security-bundle/blob/master/CHANGELOG.md
4.1.0
The logout_on_user_change firewall option is deprecated and will be removed in 5.0.
4.0.0
the firewall option logout_on_user_change is now always true, which will trigger a logout if the user changes between requests
3.4.0
Added logout_on_user_change to the firewall options. This config item will trigger a logout when the user has changed. Should be set to true to avoid deprecations in the configuration.
The option wasn't documented by the time of writing this answer: https://github.com/symfony/symfony-docs/issues/8428, but it now is: https://symfony.com/doc/4.4/reference/configuration/security.html#logout-on-user-change
Side note on updating to a new major release
If you want to upgrade to a new major version, always update to the latest minor version first. That means update to 2.8 before updating to 3.0 and updating to 3.4 before going to 4.0. See Symfony 4: Compose your Applications by Fabien Potencier.
Symfony 3.0 = Symfony 2.8 - deprecated features
(..)
Symfony 4.0 = Symfony 3.4 - deprecated features + a new way to develop
applications
Updating to a new major release is much easier if you're already on the latest minor release, because you can see all deprecation notices.

I haved the problem du to the getRoles function. My user didn't have any roles
When the token is contruct in UsernamePasswordToken , the token is not authenticated if there is empty roles :
class UsernamePasswordToken extends AbstractToken
{
..
public function __construct($user, $credentials, string $providerKey, array $roles = [])
{
parent::__construct($roles);
...
parent::setAuthenticated(\count($roles) > 0);
}
In other word, when user have empty roles, he is not authenticated.
I solved my problem by coding getRoles in my user class like the current doc https://symfony.com/doc/current/security.html#roles to guarantee every user at least has ROLE_USER
public function getRoles()
{
$roles = $this->roles;
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
Hope that help.

Related

Symfony 3 unable to login with ajax

First, I am not using FOSUserBundle in this project. So, let's get that out of the way.
I am able to register an user, but unable to log him in.
I verified that form is posted to LoginController and that it generates the authenticationUtils object, but it stops short of generating an error, even if there is one on line below:
$error = $authUtils->getLastAuthenticationError();
Otherwise it does not generate any error. It fails silently. The _wdt continues to show as anonymous even if I provide the correct credentials.
security.yml
security:
encoders:
UsedBundle\Entity\User:
algorithm: bcrypt
providers:
db_provider:
entity:
class: UsedBundle:User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
provider: db_provider
form_login:
username_parameter: _email
The login controller:
UsedBundle\Controller\LoginController
namespace UsedBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
class LoginController extends Controller
{
/**
* #Route("/login", name="login")
*/
public function loginAction(Request $request)
{
if ($request->isMethod('POST')) {
var_dump($_POST);
$authUtils = $this->get('security.authentication_utils');
// get the login error if there is one
$error = $authUtils->getLastAuthenticationError();
var_dump($error);
var_dump($authUtils);
if(isset($error)){
$message = $error->getMessageData();
var_dump($message);
}
// last username entered by the user
$lastUsername= $authUtils->getLastUsername();
return new JsonResponse(array(
'last_username' => $lastUsername,
'error' => $error,)
);
}else{
return $this->render('common/login.html.twig');
}
}
}
The form template:
app\Resources\Views\Common\login.html.twig
{% if error is defined and error is not null %}
{{ dump(error) }}
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% else %}
<form action="" method="post" name="login_form" id="login_form" >
<div class="contact" >
<input type="email" id="email" name="_email" class="form-control" placeholder="e-mail" value=" {% if last_username is defined %}
{{ last_username }}
{% endif %}
" />
</div>
<div class="contact" >
<input type="password" id="password" name="_password" placeholder="mot de passe" />
</div>
<div>
<button type="submit" class="sub_ok btn btn-sm" name="submit" >Valider</button>
</div>
</form>
{% endif %}
The User entity has the getUsername() method set up to return the email:
namespace UsedBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="UsedBundle\Repository\UserRepository")
* #UniqueEntity(fields="email", message="Email already taken")
* #UniqueEntity(fields="avatar", message="Username already taken")
*/
class User implements UserInterface, \Serializable
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=50, unique=true)
* #Assert\Regex(
* pattern="/^[A-Za-z0-9\s_\-.]{5,50}$/",
* message="Minimum 5 caracteres, max 50."
* )
*/
private $avatar;
/**
* #ORM\Column(type="string", length=50)
* #Assert\Regex(
* pattern="/^[a-zA-Z\s]{5,50}$/",
* message="Minimum 5 lettres, max 50."
* )
*/
private $name;
/**
* #ORM\Column(type="string", length=64)
*/
private $password;
/**
* #Assert\Length(max=4096)
* #Assert\Regex(
* pattern="/^.{8,50}$/",
* message="Minimum 8 caracteres, max 50."
* )
*/
private $plainPassword;
/**
* #ORM\Column(type="string", length=100, unique=true)
* #Assert\NotBlank()
* #Assert\Email()
*/
private $email;
/**
* #ORM\Column(type="string", length=50)
* #Assert\Regex(
* pattern="/^[0-9]{10,20}$/",
* message="Minimum 5 lettres, max 50."
* )
*/
private $phone;
/**
* #ORM\Column(type="string", length=50)
*/
private $role;
/**
* #ORM\Column(type="boolean")
*/
private $isActive;
/**
* #ORM\Column(type="string", length=64)
*/
private $userKey;
/**
* #ORM\Column(type="datetime")
* #Assert\DateTime()
*/
private $userKeyTime;
/**
* #ORM\Column(type="datetime")
* #Assert\DateTime()
*/
private $dateReg;
/**
* #ORM\Column(type="string", length=10)
*/
private $blogSubs;
/**
* Many users for one city
* #ORM\ManyToOne(targetEntity="City",inversedBy="users")
* #ORM\JoinColumn(name="city_id", referencedColumnName="id")
*/
private $cityId;
/**
* one visitor may correspond to one user
*
* #ORM\OneToOne(targetEntity="Visitor", mappedBy="userId")
*/
private $visitor;
public function __construct()
{
$this->isActive = false;
$this->role = 'ROLE_USER';
//$this->blogSubs = 0;
}
public function getUsername()
{
return $this->email;
}
public function getSalt()
{
return null;
}
public function getPassword()
{
return $this->password;
}
public function getRoles()
{
return array('ROLE_USER');
}
public function eraseCredentials()
{
}
/** #see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
// $this->salt,
));
}
/** #see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
// $this->salt
) = unserialize($serialized);
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set avatar
*
* #param string $avatar
*
* #return User
*/
public function setAvatar($avatar)
{
$this->avatar = $avatar;
return $this;
}
/**
* Get avatar
*
* #return string
*/
public function getAvatar()
{
return $this->avatar;
}
/**
* Set name
*
* #param string $name
*
* #return User
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* 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 phone
*
* #param string $phone
*
* #return User
*/
public function setPhone($phone)
{
$this->phone = $phone;
return $this;
}
/**
* Get phone
*
* #return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* Set isActive
*
* #param boolean $isActive
*
* #return User
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get isActive
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* Set userKey
*
* #param string $email
*
* #return User
*/
public function setUserKey( $email )
{
$cur_time = time();
$this->userKey = password_hash($email.$cur_time, PASSWORD_BCRYPT )."\n";
return $this;
}
/**
* Get userKey
*
* #return string
*/
public function getUserKey()
{
return $this->userKey;
}
/**
* Set userKeyTime
*
*
* #return User
*/
public function setUserKeyTime( $hours_added = null )
{
if ( $hours_added === null ){
$hours_added = 20;
$literal_time = \DateTime::createFromFormat('Y-m-d H:i:s',date("Y-m-d H:i:s", strtotime('+' . $hours_added . ' hours')));
}else{
$literal_time = \DateTime::createFromFormat('Y-m-d H:i:s',date("Y-m-d H:i:s", time()));
}
$this->userKeyTime = $literal_time;
return $this;
}
/**
* Get userKeyTime
*
* #return \DateTime
*/
public function getUserKeyTime()
{
return $this->userKeyTime;
}
/**
* Get dateReg
*
* #return \DateTime
*/
public function getDateReg()
{
return $this->dateReg;
}
/**
* Set dateReg
*
* #return \DateTime
*/
public function setDateReg()
{
$literal_time = \DateTime::createFromFormat('Y-m-d H:i:s',date("Y-m-d H:i:s"));
$this->dateReg = $literal_time;
return $this;
}
/**
* Set role
*
* #param string $role
*
* #return User
*/
public function setRole($role)
{
$this->role = $role;
return $this;
}
/**
* Get role
*
* #return string
*/
public function getRole()
{
return $this->role;
}
/**
* Set blogSubs
*
* #param string $blogSubs
*
* #return User
*/
public function setBlogSubs($blogSubs)
{
$this->blogSubs = $blogSubs;
return $this;
}
/**
* Get blogSubs
*
* #return string
*/
public function getBlogSubs()
{
return $this->blogSubs;
}
/**
* Get plainPassword
*
* #return string
*/
public function getPlainPassword()
{
return $this->plainPassword;
}
/**
* Set cityId
*
* #param \UsedBundle\Entity\City $cityId
*
* #return User
*/
public function setCityId(\UsedBundle\Entity\City $cityId = null)
{
$this->cityId = $cityId;
return $this;
}
/**
* Get cityId
*
* #return \UsedBundle\Entity\City
*/
public function getCityId()
{
return $this->cityId;
}
/**
* Set models
*
* #param \UsedBundle\Entity\Visitor $models
*
* #return User
*/
public function setModels(\UsedBundle\Entity\Visitor $models = null)
{
$this->models = $models;
return $this;
}
/**
* Get models
*
* #return \UsedBundle\Entity\Visitor
*/
public function getModels()
{
return $this->models;
}
/**
* Set visitor
*
* #param \UsedBundle\Entity\Visitor $visitor
*
* #return User
*/
public function setVisitor(\UsedBundle\Entity\Visitor $visitor = null)
{
$this->visitor = $visitor;
return $this;
}
/**
* Get visitor
*
* #return \UsedBundle\Entity\Visitor
*/
public function getVisitor()
{
return $this->visitor;
}
}
The form is submitted via Ajax, as follows:
$(document).ready(function() {
$('#login_form').submit(function(e) {
var str = $("#login_form").serialize();
$.ajax({
url: "/login",
type: "POST",
dataType: "json",
data: str,
success: function(data) {
alert(data);
}
e.preventDefault(); //STOP default action
});
});
});
I am adding the output below from Firebug. I am not exactly sure how it came about, but it shows the role property empty. Still not sure why. All users have ROLE_USER on the db
object(Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken)#2384 (6) {
["credentials":"Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken":private]=>
string(8) "senha444"
["providerKey":"Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken":private]=>
string(4) "main"
["user":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
string(22) "myemail#gmail.com"
["roles":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
array(0) {
}
["authenticated":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
bool(false)
["attributes":"Symfony\Component\Security\Core\Authentication\Token\AbstractToken":private]=>
array(0) {
}
This would not work as set up above. Symfony does not play well with Ajax, so one needs to customize the login.
I have added an answer on this question with the whole setup.

Symfony Security AdvancedUserInterface

Welcome,
I have some problem with user Authentication. My security.yml file:
security:
firewalls:
default:
anonymous: ~
http_basic: ~
provider: our_db_provider
logout:
path: /logout
providers:
our_db_provider:
entity:
class: CmsUserBundle:User
property: username
encoders:
Cms\UserBundle\Entity\User: plaintext
My user entity:
<?php
namespace Cms\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\HasLifecycleCallbacks()
* #ORM\Entity(repositoryClass="Cms\UserBundle\Entity\UserRepository")
*/
class User implements AdvancedUserInterface, \Serializable
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=64)
*/
private $username;
/**
* #ORM\Column(type="string", length= 64)
*/
private $email;
/**
* #ORM\Column(type="string", length=64)
*/
private $password;
/**
* #ORM\Column(type="date", length=128)
*/
private $dateOfBirthday;
/**
* #ORM\Column(type="text")
*/
private $about;
/**
* #ORM\Column(type="string", length=64)
*/
private $salt;
/**
* #ORM\ManyToOne(targetEntity="Cms\UserBundle\Entity\Role")
* #ORM\JoinColumn(name="role_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $roles;
/**
* #ORM\Column(type="string", length=255)
*/
private $eraseCredentials;
/**
* #ORM\Column(name="is_active", type="boolean", options={"default": 0})
*/
private $isActive;
/**
* #ORM\Column(type="string", nullable=true)
* #Assert\Image()
*/
private $profilePicturePath;
/**
* #ORM\Column(type="string", nullable=true)
*/
private $activatedHash;
public function __construct()
{
$this->setActivatedHash(bin2hex(random_bytes(36)));
}
public function getSalt()
{
return $this->salt;
}
public function getPassword()
{
return $this->password;
}
public function getRoles()
{
return array($this->roles);
}
public function eraseCredentials()
{
}
public function getUsername()
{
return $this->username;
}
/**
* Get eraseCredentials
*
* #return string
*/
public function getEraseCredentials()
{
return $this->eraseCredentials;
}
/**
* Set isActive
*
* #param boolean $isActive
* #return User
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get isActive
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* 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;
}
/**
* 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 password
*
* #param string $password
*
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Set dateOfBirthday
*
* #param \DateTime $dateOfBirthday
*
* #return User
*/
public function setDateOfBirthday($dateOfBirthday)
{
$this->dateOfBirthday = $dateOfBirthday;
return $this;
}
/**
* Get dateOfBirthday
*
* #return \DateTime
*/
public function getDateOfBirthday()
{
return $this->dateOfBirthday;
}
/**
* Set about
*
* #param string $about
*
* #return User
*/
public function setAbout($about)
{
$this->about = $about;
return $this;
}
/**
* Get about
*
* #return string
*/
public function getAbout()
{
return $this->about;
}
/**
* Set salt
*
* #param string $salt
*
* #return User
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Set eraseCredentials
*
* #param string $eraseCredentials
*
* #return User
*/
public function setEraseCredentials($eraseCredentials)
{
$this->eraseCredentials = $eraseCredentials;
return $this;
}
/**
* Set roles
*
* #param \Cms\UserBundle\Entity\Role $roles
*
* #return User
*/
public function setRoles(\Cms\UserBundle\Entity\Role $roles = null)
{
$this->roles = $roles;
return $this;
}
/**
* Set profilePicturePath
*
* #param string $profilePicturePath
*
* #return User
*/
public function setProfilePicturePath($profilePicturePath)
{
$this->profilePicturePath = $profilePicturePath;
return $this;
}
/**
* Get profilePicturePath
*
* #return string
*/
public function getProfilePicturePath()
{
return $this->profilePicturePath;
}
/**
* Serialization is required to FileUploader
* #return string
*/
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->salt,
$this->password,
$this->roles,
$this->isActive
));
}
/**
* #param string $serialized
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->salt,
$this->password,
$this->roles,
$this->isActive
) = unserialize($serialized);
}
/**
* Set activatedHash
*
* #param string $activatedHash
*
* #return User
*/
public function setActivatedHash($activatedHash)
{
$this->activatedHash = $activatedHash;
return $this;
}
/**
* Get activatedHash
*
* #return string
*/
public function getActivatedHash()
{
return $this->activatedHash;
}
public function isAccountNonExpired()
{
return true;
}
public function isAccountNonLocked()
{
return true;
}
public function isCredentialsNonExpired()
{
return true;
}
public function isEnabled()
{
return $this->getIsActive();
}
}
And in my Controller:
$token = new UsernamePasswordToken($foundUser, $foundUser->getPassword(), 'default', array($role->getRole()) );
$this->get('security.token_storage')->setToken($token);
My problem is that every time user is success Authenticated, even if my isEnabled() function return false. Thanks for help.

Symfony2 Logged in but NOT Authenticated

security.yml
security:
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN]
encoders:
Karl\UserBundle\Entity\User: plaintext
providers:
main:
entity:
class: Karl\UserBundle\Entity\User
property: email
firewalls:
secured_area:
pattern: ^/
anonymous: ~
provider: main
form_login:
check_path: login_check
login_path: login
username_parameter: _email
logout:
path: logout
target: /
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
If i put an access control for a certain page, the problem will go away but previously it did not need the acl and it will work fine, anyone know whats the problem or did i do something wrong with the firewall?
The user is logged in with ROLE_USER and the username is also detected but not authenticated.
Ok i found out what is the problem,
For the User Entity, i took out \Serializable and it's working now. One question, how does taking it out make the user authenticated?
/**
* User
*
* #ORM\Table(name="User")
* #ORM\Entity
* #UniqueEntity("email")
*/
class User implements UserInterface, \Serializable <--taken out and problem solved but why?
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #Assert\NotBlank();
* #var string
* #ORM\Column(name="username", type="string", length=32)
*/
private $username;
/**
* #Assert\NotBlank();
* #Assert\Email();
* #var string
* #ORM\Column(name="email", type="string", length=128)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $password;
/**
* #var string
*
* #ORM\Column(name="contact", type="string", length=32)
*/
private $contact;
/**
* #var \DateTime
*
* #ORM\Column(name="date_create", type="datetime")
*/
private $dateCreate;
/**
* #var \DateTime
*
* #ORM\Column(name="date_last_login", type="datetime")
*/
private $dateLastLogin;
/**
* #var integer
*
* #ORM\Column(name="login_count", type="integer")
*/
private $loginCount;
/**
* #var string
*
* #ORM\Column(name="ip_address", type="string", length=32)
*/
private $ipAddress;
/**
* 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;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* 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 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 contact
*
* #param string $contact
* #return User
*/
public function setContact($contact)
{
$this->contact = $contact;
return $this;
}
/**
* Get contact
*
* #return string
*/
public function getContact()
{
return $this->contact;
}
/**
* Set dateCreate
*
* #param \DateTime $dateCreate
* #return User
*/
public function setDateCreate($dateCreate)
{
$this->dateCreate = $dateCreate;
return $this;
}
/**
* Get dateCreate
*
* #return \DateTime
*/
public function getDateCreate()
{
return $this->dateCreate;
}
/**
* Set dateLastLogin
*
* #param \DateTime $dateLastLogin
* #return User
*/
public function setDateLastLogin($dateLastLogin)
{
$this->dateLastLogin = $dateLastLogin;
return $this;
}
/**
* Get dateLastLogin
*
* #return \DateTime
*/
public function getDateLastLogin()
{
return $this->dateLastLogin;
}
/**
* Set loginCount
*
* #param integer $loginCount
* #return User
*/
public function setLoginCount($loginCount)
{
$this->loginCount = $loginCount;
return $this;
}
/**
* Get loginCount
*
* #return integer
*/
public function getLoginCount()
{
return $this->loginCount;
}
/**
* Set ipAddress
*
* #param string $ipAddress
* #return User
*/
public function setIpAddress($ipAddress)
{
$this->ipAddress = $ipAddress;
return $this;
}
/**
* Get ipAddress
*
* #return string
*/
public function getIpAddress()
{
return $this->ipAddress;
}
/**
* #inheritDoc
*/
public function getRoles(){
return array('ROLE_USER');
}
/**
* #inheritDoc
*/
public function getSalt(){
//return $this->salt;
return null;
}
public function eraseCredentials(){
}
/**
* #inheritDoc
*/
public function serialize()
{
return serialize(array(
$this->id,
$this->email,
$this->password,
// see section on salt below
// $this->salt,
));
}
/**
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->email,
$this->password,
// see section on salt below
// $this->salt
) = unserialize($serialized);
}
}

Symfony2 Login SHA512 - Bad Credentials

I've been through literally every SO post regarding this issue but I still can't find my bug. I'm trying to get my login working using sha512. I don't think the password is being encoded correctly, as I've checked on this site. The password I used was "asdf", the salt being generated is "fe739a9eafaff0a5b5091d51e1642a34", and the password stored in my DB is "HzK/fSfJjLQAuAgUhxBzQaPT8cJQ0/05pt5zcYoSM4d7Dxd/WDBiJYXIMmFF70I+". Is this my problem? I simply cannot get past the damned "Bad Credentials" thing. My code is below...
security.yml
security:
encoders:
MyBundle\MainBundle\Entity\SystemUser:
algorithm: sha512
iterations: 1
role_hierarchy:
ROLE_STUDENT:
ROLE_GUARDIAN:
ROLE_TEACHER:
ROLE_SCHOOL_ADMIN: ROLE_STUDENT, ROLE_GUARDIAN
ROLE_ADMIN: ROLE_SCHOOL_ADMIN, ROLE_STUDENT, ROLE_GUARDIAN
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
users:
entity: { class: MyBundleMainBundle:SystemUser }
firewalls:
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: login
check_path: login_check
csrf_provider: form.csrf_provider
csrf_parameter: _csrf_token
always_use_default_target_path: true
default_target_path: /dashboard
logout: true
anonymous: true
Then, my SystemUser class (sorry it's so long, just want to be comprehensive here)
<?php
namespace MyBundle\MainBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Component\Validator\Constraints\Collection;
/**
* SystemUser
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="MyBundle\MainBundle\Entity\Repository\SystemUserRepository")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="discr", type="integer")
* #ORM\DiscriminatorMap({"0" = "SystemUser", "1" = "SchoolAdmin", "2" = "Teacher", "3" = "Student", "4" = "Guardian"})
*/
class SystemUser implements AdvancedUserInterface, \Serializable {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(type="string", length=50)
*/
protected $username;
/**
* #var string
*
* #ORM\Column(type="string", length=255)
*/
protected $email;
/**
* #var string
*
* #ORM\Column(type="string", length=32)
*/
protected $salt;
/**
* #var string
*
* #ORM\Column(type="string", length=64)
*/
protected $password;
/**
* #var bool
*
* #ORM\Column(type="boolean", name="is_active")
*/
protected $isActive;
/**
* #var string
* #ORM\Column(name="birth_date", type="date")
*/
protected $birthDate;
/**
* #var string
* #ORM\Column(name="cellphone", type="string", length=10)
*/
protected $cellphone;
/**
* #var ArrayCollection
* #ORM\ManyToMany(targetEntity="Role", inversedBy="users")
*/
protected $roles;
/**
* #var integer
* Use this to map to the discr column...
*/
protected $discr;
/**
*
*
*
*
* Begin methods
*
*
*
*/
public function __construct() {
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
$this->roles = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set birthDate
*
* #param \DateTime $birthDate
* #return SystemUser
*/
public function setBirthDate($birthDate)
{
$this->birthDate = $birthDate;
return $this;
}
/**
* Get birthDate
*
* #return \DateTime
*/
public function getBirthDate()
{
return $this->birthDate;
}
/**
* Set cellphone
*
* #param string $cellphone
* #return SystemUser
*/
public function setCellphone($cellphone)
{
$this->cellphone = $cellphone;
return $this;
}
/**
* Get cellphone
*
* #return string
*/
public function getCellphone()
{
return $this->cellphone;
}
/**
* (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,
));
}
/**
* (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) = unserialize($serialized);
}
/**
* 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;
}
/**
* 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;
}
/**
* 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()
{
return $this->salt;
}
/**
* Returns the username used to authenticate the user.
*
* #return string The username
*/
public function getUsername()
{
return $this->username;
}
/**
* 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.
}
/**
* Checks whether the user's account has expired.
*
* Internally, if this method returns false, the authentication system
* will throw an AccountExpiredException and prevent login.
*
* #return Boolean true if the user's account is non expired, false otherwise
*
* #see AccountExpiredException
*/
public function isAccountNonExpired()
{
return true;
}
/**
* Checks whether the user is locked.
*
* Internally, if this method returns false, the authentication system
* will throw a LockedException and prevent login.
*
* #return Boolean true if the user is not locked, false otherwise
*
* #see LockedException
*/
public function isAccountNonLocked()
{
return true;
}
/**
* Checks whether the user's credentials (password) has expired.
*
* Internally, if this method returns false, the authentication system
* will throw a CredentialsExpiredException and prevent login.
*
* #return Boolean true if the user's credentials are non expired, false otherwise
*
* #see CredentialsExpiredException
*/
public function isCredentialsNonExpired()
{
return true;
}
/**
* Checks whether the user is enabled.
*
* Internally, if this method returns false, the authentication system
* will throw a DisabledException and prevent login.
*
* #return Boolean true if the user is enabled, false otherwise
*
* #see DisabledException
*/
public function isEnabled()
{
return $this->isActive;
}
/**
* Set username
*
* #param string $username
* #return SystemUser
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Set email
*
* #param string $email
* #return SystemUser
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set salt
*
* #param string $salt
* #return SystemUser
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Set password
*
* #param string $password
* #return SystemUser
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Set isActive
*
* #param boolean $isActive
* #return SystemUser
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get isActive
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* Add roles
*
* #param \MyBundle\MainBundle\Entity\Role $role
* #return SystemUser
*/
public function addRole(\MyBundle\MainBundle\Entity\Role $role)
{
$this->roles[] = $role;
return $this;
}
public function removeRole(\MyBundle\MainBundle\Entity\Role $role) {
$this->roles->removeElement($role);
}
/**
* Get discr
*
* #return int
*/
public function getDiscr() {
return $this->discr;
}
/**
* Set discr
*
* #param $discr
* #return \MyBundle\MainBundle\Entity\SystemUser
*/
public function setDiscr($discr) {
$this->discr = $discr;
return $this;
}
}
My SystemUserRepository
class SystemUserRepository extends EntityRepository implements UserProviderInterface
{
public function loadUserByUsername($username)
{
$query = $this->createQueryBuilder('su')
->select('su, sr') //SystemUser, SystemRoles
->leftJoin('su.roles', 'sr')
->where('su.username = :username OR su.email = :email')
->setParameter('username', $username)
->setParameter('email', $username)
->getQuery();
try {
$user = $query->getSingleResult();
} catch (NoResultException $e) {
$message = 'Unable to find user \'' . $username . '\'';
throw new UsernameNotFoundException($message, 0, $e);
}
return $user;
}
public function refreshUser(UserInterface $user)
{
$class = get_class($user);
if (!$this->supportsClass($class)) {
throw new UnsupportedUserException(
'Instances of \'' . $class . '\' are not supported'
);
}
return $this->find($user->getId());
}
public function supportsClass($class)
{
return $this->getEntityName() === $class
|| is_subclass_of($class, $this->getEntityName());
}
}
and finally my Login
public function loginAction() {
$request = $this->getRequest();
$session = $request->getSession();
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(
'MyBundleMainBundle:Security:login.html.twig',
array(
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
'csrf_token' => $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate'),
)
);
}
Oh, and if it's of any consequence, my registration controller.
public function createUserAction(Request $request) {
$entityManager = $this->getDoctrine()->getManager();
$form = $this->createForm('user_registration', new Registration());
$form->handleRequest($request);
if ($form->isValid()) {
$registration = $form->getData();
//Handle encoding here...
$encoderFactory = $this->get('security.encoder_factory');
$encoder = $encoderFactory->getEncoder($registration->getUser());
$password = $encoder->encodePassword($registration->getUser()->getPassword(), $registration->getUser()->getSalt());
$registration->getUser()->setPassword($password);
$entityManager->persist($registration->getUser());
$entityManager->flush();
return $this->redirect($this->generateUrl('dashboard_homepage'));
}
return $this->render(
'MyBundleMainBundle:Security:registration.html.twig',
array(
'form' => $form->createView()
)
);
}
Sorry for the long post, hope someone can help me out here! Thanks so much!
change the following code in your SystemUser class:
/**
* #var string
*
* #ORM\Column(type="string", length=64)
*/
protected $password;
to
/**
* #var string
*
* #ORM\Column(type="string", length=255)
*/
protected $password;
I stumbled upon the same problem as you after following the guides on symfony.com. By comparing the results from the hashed password before and after being persisted to the database I could see that the length of the hashed password was 88 characters long, thus it was being truncated to 64 characters after being persisted to the database.
FOSUserBundle is also using a length of 255 on their password field, so I suppose it's a legit change.
I'm guessing you have already solved this problem since it was a while ago you posted it, but i thought I would help others out who, like I did, came here with the same problem.

Symfony2 - can't log in (user repository)

I am in a bit of a problem...
Folowed the handbook of Symfony2 and now i am stuck with logging myself in :s
Any help would be welcome for this newbie.
so this is my users entity:
<?php
namespace SocialGeo\BackendBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\EquatableInterface;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Doctrine\Common\Collections\ArrayCollection;
/**
* SocialGeo\BackendBundle\Entity\Users
*/
class Users implements AdvancedUserInterface
{
/**
* #var integer $userId
*/
private $userId;
/**
* #var string $username
*/
private $username;
/**
* #ORM\Column(type="string", length=60)
*/
private $salt;
/**
* #var string $userPassword
*/
private $userPassword;
/**
* #var string $userEmail
*/
private $userEmail;
/**
* #var boolean $userActive
*/
private $userActive;
/**
* #var string $userFavourites
*/
private $userFavourites;
/**
* #var integer $userScore
*/
private $userScore;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*/
private $rolesRole;
/**
* Constructor
*/
public function __construct()
{
$this->rolesRole = new ArrayCollection();
$this->salt = md5(uniqid(null, true));
}
/**
* Get userId
*
* #return integer
*/
public function getUserId()
{
return $this->userId;
}
/**
* Set username
*
* #param string $username
* #return Users
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set userPassword
*
* #param string $userPassword
* #return Users
*/
public function setUserPassword($userPassword)
{
$this->userPassword = $userPassword;
return $this;
}
/**
* Get userPassword
*
* #return string
*/
public function getUserPassword()
{
return $this->userPassword;
}
/**
* Set userEmail
*
* #param string $userEmail
* #return Users
*/
public function setUserEmail($userEmail)
{
$this->userEmail = $userEmail;
return $this;
}
/**
* Get userEmail
*
* #return string
*/
public function getUserEmail()
{
return $this->userEmail;
}
/**
* Set userActive
*
* #param boolean $userActive
* #return Users
*/
public function setUserActive($userActive)
{
$this->userActive = $userActive;
return $this;
}
/**
* Get userActive
*
* #return boolean
*/
public function getUserActive()
{
return $this->userActive;
}
/**
* Set userFavourites
*
* #param string $userFavourites
* #return Users
*/
public function setUserFavourites($userFavourites)
{
$this->userFavourites = $userFavourites;
return $this;
}
/**
* Get userFavourites
*
* #return string
*/
public function getUserFavourites()
{
return $this->userFavourites;
}
/**
* Set userScore
*
* #param integer $userScore
* #return Users
*/
public function setUserScore($userScore)
{
$this->userScore = $userScore;
return $this;
}
/**
* Get userScore
*
* #return integer
*/
public function getUserScore()
{
return $this->userScore;
}
/**
* Add rolesRole
*
* #param SocialGeo\BackendBundle\Entity\Roles $rolesRole
* #return Users
*/
public function addRolesRole(\SocialGeo\BackendBundle\Entity\Roles $rolesRole)
{
$this->rolesRole[] = $rolesRole;
return $this;
}
/**
* Remove rolesRole
*
* #param SocialGeo\BackendBundle\Entity\Roles $rolesRole
*/
public function removeRolesRole(\SocialGeo\BackendBundle\Entity\Roles $rolesRole)
{
$this->rolesRole->removeElement($rolesRole);
}
/**
* Get rolesRole
*
* #return Doctrine\Common\Collections\Collection
*/
public function getRolesRole()
{
return $this->rolesRole->toArray();
}
public function eraseCredentials()
{
}
public function getPassword()
{
return $this->userPassword;
}
public function getRoles()
{
//return $this->groups->toArray();
return $this->getRolesRole();
}
public function getSalt()
{
return $this->salt;
}
public function isEqualTo(UserInterface $users)
{
return $this->username === $users->getUsername();
}
public function isAccountNonExpired() {
return true;
}
public function isAccountNonLocked() {
return true;
}
public function isCredentialsNonExpired() {
return true;
}
public function isEnabled() {
return $this->userActive;
}
}
my roles entity:
<?php
namespace SocialGeo\BackendBundle\Entity;
use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* SocialGeo\BackendBundle\Entity\Roles
*/
class Roles implements RoleInterface
{
/**
* #var integer $roleId
*/
private $roleId;
/**
* #var string $roleName
*/
private $roleName;
/**
* #ORM\Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/**
* #var string $roleDescription
*/
private $roleDescription;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*/
private $usersUser;
/**
* Constructor
*/
public function __construct()
{
$this->usersUser = new ArrayCollection();
}
/**
* Get roleId
*
* #return integer
*/
public function getRoleId()
{
return $this->roleId;
}
/**
* Set roleName
*
* #param string $roleName
* #return Roles
*/
public function setRoleName($roleName)
{
$this->roleName = $roleName;
return $this;
}
/**
* Get roleName
*
* #return string
*/
public function getRoleName()
{
return $this->roleName;
}
/**
* Set roleDescription
*
* #param string $roleDescription
* #return Roles
*/
public function setRoleDescription($roleDescription)
{
$this->roleDescription = $roleDescription;
return $this;
}
/**
* Get roleDescription
*
* #return string
*/
public function getRoleDescription()
{
return $this->roleDescription;
}
/**
* Add usersUser
*
* #param SocialGeo\BackendBundle\Entity\Users $usersUser
* #return Roles
*/
public function addUsersUser(\SocialGeo\BackendBundle\Entity\Users $usersUser)
{
$this->usersUser[] = $usersUser;
return $this;
}
/**
* Remove usersUser
*
* #param SocialGeo\BackendBundle\Entity\Users $usersUser
*/
public function removeUsersUser(\SocialGeo\BackendBundle\Entity\Users $usersUser)
{
$this->usersUser->removeElement($usersUser);
}
/**
* Get usersUser
*
* #return Doctrine\Common\Collections\Collection
*/
public function getUsersUser()
{
return $this->usersUser;
}
public function getRole() {
return $this->role;
}
}
userrepository entity:
<?php
namespace SocialGeo\BackendBundle\Entity;
use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* SocialGeo\BackendBundle\Entity\Roles
*/
class Roles implements RoleInterface
{
/**
* #var integer $roleId
*/
private $roleId;
/**
* #var string $roleName
*/
private $roleName;
/**
* #ORM\Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/**
* #var string $roleDescription
*/
private $roleDescription;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*/
private $usersUser;
/**
* Constructor
*/
public function __construct()
{
$this->usersUser = new ArrayCollection();
}
/**
* Get roleId
*
* #return integer
*/
public function getRoleId()
{
return $this->roleId;
}
/**
* Set roleName
*
* #param string $roleName
* #return Roles
*/
public function setRoleName($roleName)
{
$this->roleName = $roleName;
return $this;
}
/**
* Get roleName
*
* #return string
*/
public function getRoleName()
{
return $this->roleName;
}
/**
* Set roleDescription
*
* #param string $roleDescription
* #return Roles
*/
public function setRoleDescription($roleDescription)
{
$this->roleDescription = $roleDescription;
return $this;
}
/**
* Get roleDescription
*
* #return string
*/
public function getRoleDescription()
{
return $this->roleDescription;
}
/**
* Add usersUser
*
* #param SocialGeo\BackendBundle\Entity\Users $usersUser
* #return Roles
*/
public function addUsersUser(\SocialGeo\BackendBundle\Entity\Users $usersUser)
{
$this->usersUser[] = $usersUser;
return $this;
}
/**
* Remove usersUser
*
* #param SocialGeo\BackendBundle\Entity\Users $usersUser
*/
public function removeUsersUser(\SocialGeo\BackendBundle\Entity\Users $usersUser)
{
$this->usersUser->removeElement($usersUser);
}
/**
* Get usersUser
*
* #return Doctrine\Common\Collections\Collection
*/
public function getUsersUser()
{
return $this->usersUser;
}
public function getRole() {
return $this->role;
}
}
and last one: security.yml:
security:
encoders:
SocialGeo\BackendBundle\Entity\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:
users:
entity: { class: SocialGeoBackendBundle:Users }
firewalls:
admin_area:
pattern: ^/users
http_basic: ~
access_control:
- { path: ^/login, roles: ROLE_ADMIN }
The problem is that my app keeps asking me to log in everytime, but i can't get in (everytimei go to /users page). Home is accesible.
So when i go to /users a basic http: pops out of the browser and asks me my credentials, when i fill them in and press enter, i get the same popup of the browser, asking me to log in...
edit: my salt in the database for evey user is: 7308e59b97f6957fb42d66f894793079
and my password for everyuser is 'pass' hashed with sha1 to : 9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684
Your password is hashed incorrectly. You're supposed to use the salt together with the cleartext password. Try prefixing your password with the salt before hashing it.
update users set password = sha1(concat('7308e59b97f6957fb42d66f894793079', 'pass'))

Categories