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);
}
}
Related
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.
i try register new user by this code, and i want encode password with security.password_encoder before persist password property of user has value but i see this error
An exception occurred while executing 'INSERT INTO user (name, family, username, email, roles, password, salt) VALUES (?, ?, ?, ?, ?, ?, ?)' with params ["root", "rooti", "root", "root#examl.com", "[\"ROLE_ADMIN\"]", null, "$2y$13$70JDWmzFF0fuJyVCaB3/ueISm3FgWRBMLAkSJqcQouNAh3qPnzcg."]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'password' cannot be null
my method is here :
public function newAction(Request $request)
{
$user = new User();
$form = $this->createForm('AppBundle\Form\UserType', $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$encoder = $this->get("security.password_encoder");
$encoded = $encoder->encodePassword($user, $user->getPlainPassword());
$user->setPassword($encoded);
$user->setRoles(array('ROLE_ADMIN'));
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
return $this->redirectToRoute('user_show', array('id' => $user->getId()));
}
return $this->render('user/new.html.twig', array(
'user' => $user,
'form' => $form->createView(),
));
}
and this is my User entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
*/
class User implements UserInterface
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="family", type="string", length=255)
*/
private $family;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=255, unique=true)
*/
private $username;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255)
*/
private $email;
/**
* #var array
*
* #ORM\Column(name="roles", type="json_array")
*/
private $roles;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $salt;
/**
* #var string
*
* #ORM\Column(name="salt", type="string", length=10)
*/
private $password;
/**
* #var string
* #Assert\NotBlank()
* #Assert\Length(max=4096)
*/
private $plainPassword;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* 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 family
*
* #param string $family
*
* #return User
*/
public function setFamily($family)
{
$this->family = $family;
return $this;
}
/**
* Get family
*
* #return string
*/
public function getFamily()
{
return $this->family;
}
/**
* 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 roles
*
* #param array $roles
*
* #return User
*/
public function setRoles($roles)
{
$this->roles = $roles;
return $this;
}
public function getPlainPassword()
{
return $this->plainPassword;
}
public function setPlainPassword($password)
{
$this->plainPassword = $password;
}
/**
* Get roles
*
* #return array
*/
public function getRoles()
{
$roles = $this->roles;
// guarantees that a user always has at least one role for security
if (empty($roles)) {
$roles[] = 'ROLE_USER';
}
return array_unique($roles);
}
/**
* 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 salt
*
* #param string $salt
*
* #return User
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Get salt
*
* #return string
*/
public function getSalt()
{
return;
}
public function eraseCredentials()
{
}
}
and i set security algorithm to bcrypt is security.yml
is here
security:
encoders:
AppBundle\Entity\User: bcrypt
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
providers:
database_users:
entity: { class: AppBundle:User, property: username}
firewalls:
secured_area:
pattern: ^/
anonymous: true
form_login:
login_path: login
check_path: login
csrf_token_generator: security.csrf.token_manager
logout:
path: security_logout
target: homepage
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
Your column names are mixed up here:
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $salt;
/**
* #var string
*
* #ORM\Column(name="salt", type="string", length=10)
*/
private $password;
You're storing salt in a column called password (which must be set in the database to not allow NULL although that rule is not present in the annotation) and password in a column called salt. Just flip them around:
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $password;
/**
* #var string
*
* #ORM\Column(name="salt", type="string", length=10)
*/
private $salt;
For the past few days I've been struggling with logging in a database-user using Symfony/Doctrine, and I'm pretty stuck by now (I'm new to Symfony, btw). I got the login working using the in_memory provider (to start with), but now I want to login using a database-user and I just don't know what's wrong.
I went over the documentation over and over and I think I got everything right. I don't get errors, it just says "Invalid credentials." when I try to login. I have to feeling that it has something to do with security.yml but I've tried about all I could find. Below is my code;
security.yml;
security:
providers:
provider_users:
entity:
class: AppBundle:User
property: username
encoders:
AppBundle\Entity\User:
algorithm: bcrypt
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
anonymous: ~
provider: provider_users
form_login:
login_path: login
check_path: login
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
User.php;
<?php
// src/AppBundle/Entity/User.php
namespace AppBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* AppBundle\Entity\User
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="AppBundle\Entity\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id()
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="username", type="string", length=25, unique=true)
*/
private $username;
/**
* #ORM\Column(name="salt", type="string", length=40)
*/
private $salt;
/**
* #ORM\Column(name="password", type="string", length=40)
*/
private $password;
/**
* #ORM\Column(name="email", type="string", length=60, unique=true)
*/
private $email;
/**
* #ORM\Column(name="roles", type="string")
*/
private $roles;
/**
* #ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
public function __construct()
{
$this->isActive = true;
$this->salt = base_convert(sha1(uniqid(mt_rand(), true)), 16, 36);
}
public function eraseCredentials()
{
//
}
/** #see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
));
}
/** #see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
) = unserialize($serialized);
}
/**
* 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 salt
*
* #param string $salt
*
* #return User
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Get salt
*
* #return string
*/
public function getSalt()
{
return $this->salt;
}
/**
* 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 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 roles
*
* #param string $roles
*
* #return User
*/
public function setRoles($roles)
{
$this->roles = json_encode($roles);
return $this;
}
/**
* Get roles
*
* #return string[]
*/
public function getRoles()
{
return json_decode($this->roles);
}
/**
* 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;
}
}
I also tested if I could just get the user "manually" using getRepository()->findAll(), and that looks okay;
array (size=1)
0 =>
object(AppBundle\Entity\User)[323]
private 'id' => int 20
private 'username' => string 'user' (length=4)
private 'salt' => string 'mqshzqa9syok0kw8ss4cscc84k4k804' (length=31)
private 'password' => string 'user1' (length=5)
private 'email' => string 'user#localhost.com' (length=18)
private 'roles' => string '' (length=0)
private 'isActive' => boolean true
success!
Any suggestions? Thanks in advance!
you need to encrypt the password with bcrypt. Possibly the user was in the database before adding security. Try to add another user with the encrypted password in php have for example: string crypt (string $ str [, string $ salt ] )
The string that you insert in the password field User :
user-> setPassword ('your encrypted string')
I'm having an error when I want to open a simple page. This is the full error:
ContextErrorException: Catchable Fatal Error: Object of class __PHP_Incomplete_Class could not be converted to string in /Applications/mampstack-5.4.20-0/apache2/htdocs/engelsvandenbroecke/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php line 70
What I've done in my symfony project is:
Generate entities from database
Edit User Entity for security
Edit security.yml
Added two datafixtures
This is my User Entity Class:
<?php
namespace Beachteam\BeachteamBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
/**
* User
*
* #ORM\Table(name="user", uniqueConstraints={#ORM\UniqueConstraint(name="username_UNIQUE", columns={"username"})}, indexes={#ORM\Index(name="fk_users_roles_idx", columns={"role_id"})})
* #ORM\Entity
*/
class User implements AdvancedUserInterface
{
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=45, nullable=false)
*/
private $username;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=60, nullable=false)
*/
private $password;
/**
* #var string
*
* #ORM\Column(name="salt", type="string", length=30, nullable=false)
*/
private $salt;
/**
* #var string
*
* #ORM\Column(name="firstname", type="string", length=45, nullable=false)
*/
private $firstname;
/**
* #var string
*
* #ORM\Column(name="surname", type="string", length=45, nullable=false)
*/
private $surname;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255, nullable=false)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="token", type="string", length=45, nullable=true)
*/
private $token;
/**
* #var \DateTime
*
* #ORM\Column(name="created", type="datetime", nullable=false)
*/
private $created;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \Beachteam\BeachteamBundle\Entity\Role
*
* #ORM\ManyToOne(targetEntity="Beachteam\BeachteamBundle\Entity\Role")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="role_id", referencedColumnName="id")
* })
*/
private $role;
private $plainPassword;
/**
* Constructor
*/
public function __construct()
{
$this->salt = base_convert(sha1(uniqid(mt_rand(), true)), 16, 36);
}
/**
* 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 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 salt
*
* #param string $salt
* #return User
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Get salt
*
* #return string
*/
public function getSalt()
{
return $this->salt;
}
/**
* 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 surname
*
* #param string $surname
* #return User
*/
public function setSurname($surname)
{
$this->surname = $surname;
return $this;
}
/**
* Get surname
*
* #return string
*/
public function getSurname()
{
return $this->surname;
}
/**
* 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 token
*
* #param string $token
* #return User
*/
public function setToken($token)
{
$this->token = $token;
return $this;
}
/**
* Get token
*
* #return string
*/
public function getToken()
{
return $this->token;
}
/**
* Set created
*
* #param \DateTime $created
* #return User
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created
*
* #return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set role
*
* #param \Beachteam\BeachteamBundle\Entity\Role $role
* #return User
*/
public function setRoles(\Beachteam\BeachteamBundle\Entity\Role $role = null)
{
$this->role = $role;
return $this;
}
/**
* Get role
*
* #return \Beachteam\BeachteamBundle\Entity\Role
*/
public function getRoles()
{
return array($this->role->getName());
}
public function eraseCredentials()
{
$this->setPlainPassword(null);
}
public function getPlainPassword()
{
return $this->plainPassword;
}
public function setPlainPassword($plainPassword)
{
$this->plainPassword = $plainPassword;
}
/**
* Implementation of AdvancedUserInterface method
*
* #return boolean
*/
public function isAccountNonExpired()
{
return true;
}
/**
* Implementation of AdvancedUserInterface method
*
* #return boolean
*/
public function isAccountNonLocked()
{
return true;
}
/**
* Implementation of AdvancedUserInterface method
*
* #return boolean
*/
public function isCredentialsNonExpired()
{
return true;
}
/**
* Implementation of AdvancedUserInterface method
*
* #return boolean
*/
public function isEnabled()
{
return true;
}
}
My security.yml:
security:
encoders:
Beachteam\BeachteamBundle\Entity\User:
algorithm: bcrypt
cost: 15
role_hierarchy:
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
users:
entity:
class: BeachteamBundle:User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: beach_team_loginpage
check_path: beach_team_logincheck
username_parameter: login[username]
password_parameter: login[password]
always_use_default_target_path: true
default_target_path: beach_team_adminpage
logout:
path: beach_team_logout
target: beach_team_loginpage
remember_me:
key: "%secret%"
lifetime: 31536000 # 365 days in seconds
path: /
domain: ~ # Defaults to the current domain from $_SERVER
remember_me_parameter: remember
access_control:
#- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }
For me help'd clearing cache/cookies in browser. (in browsers session was stored old version of user's entity).
This error usually means that you try to deserialze object without loaded class for that object. So you should somehow define this class (e.g. including file with it) and then deserialize it.
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.