I'm stack heeeere in security, help me please!!
I got this error 2 days ago and couldn't solve it : "The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL." My login in the index page, and the login and login_check are in the same function (indexAction).This is my security.yml file, my controller, and my entity "user" :
# you can read more about security in the related section of the documentation
# http://symfony.com/doc/current/book/security.html
security:
# http://symfony.com/doc/current/book/security.html#encoding-the-user-s-password
encoders:
#Symfony\Component\Security\Core\User\User: plaintext
CNAM\CMSBundle\Entity\user: bcrypt
# http://symfony.com/doc/current/book/security.html#hierarchical-roles
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
providers:
in_memory:
memory:
users:
user: { password: userpass, roles: [ 'ROLE_USER' ] }
admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
database:
entity:
class: CNAM\CMSBundle\Entity\user
property: username
# the main part of the security, where you can set up firewalls
# for specific sections of your app
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin_area:
pattern: ^/admin
form_login:
check_path: _default_index
login_path: _default_index
access_control:
#- { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY}
- { path: ^/admin, roles: ROLE_ADMIN}
<?php
namespace CNAM\CMSBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
use CNAM\CMSBundle\Entity\user;
use CNAM\CMSBundle\Entity\userprof;
use CNAM\CMSBundle\Entity\profil;
use CNAM\CMSBundle\Entity\privilege;
use Symfony\Component\BrowserKit\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Security\Core\Security;
class DefaultController extends Controller
{
/**
* #Route("/")
* #Template()
*/
public function indexAction(Request $request)
{
$user = new user();
$form = $this->createFormBuilder($user)
->add('id', 'text',array('attr'=>array('name'=>'login_user','required'=>'required',
'maxlength'=>'255','placeholder'=>'Votre matricule','id'=>'login_user')))
->add('password', 'password',array('attr'=>array('name'=>'login_password','required'=>'required',
'maxlength'=>'20','placeholder'=>'Mot de passe','id'=>'login_password')))
->add('Connexion', 'submit',array('attr'=>array('class'=>'btn btn-primary btn-block rounded_btn','id'=>'login_btn',
'style'=>"width:8vw;height:5vh;padding:0px 0px; position:relative;left:5vmin;top:1vmin;font-size:2vmin;")))
->getForm();
$form->handleRequest($request);
//$b_search=$this->get('session')->get('search');
$id = $request->request->get('id');
$session = $request->getSession();
if ($form->isValid()) {
$data = $form->getData();
$repository = $this
->getDoctrine()
->getManager()
->getRepository("CNAMCMSBundle:user");
$rep = $this
->getDoctrine()
->getManager()
->getRepository("CNAMCMSBundle:userprof");
$search = $repository->find($data);
$p_search=$rep->find($data);
$helper = $this->get('security.authentication_utils');
if (!$search) {
//throw $this->createNotFoundException('Utilisateur introuvable!');
}
else {
//$session=$this->get("session");
//$session->start();
// $session->set('search', $search);
$user->setEtat(1);
$em = $this->getDoctrine()->getManager();
$user=$em->merge($user);
$em->flush();
$id_prof=$p_search->getIdProfil();
switch ($id_prof)
{
case 1: return $this->redirect($this->generateUrl('cnam_cms_default_webmaster'),301);break;
case 2: $user->setRole("ROLE_ADMIN");$em = $this->getDoctrine()->getManager();$user=$em->merge($user);
$em->flush();return $this->redirect($this->generateUrl('cnam_cms_default_admin'),301);break;
case 3: return $this->redirect($this->generateUrl('cnam_cms_default_sup_med'),301);break;
case 4: return $this->redirect($this->generateUrl('cnam_cms_default_med'),301);break;
case 5: return $this->redirect($this->generateUrl('cnam_cms_default_gest_mp'),301);break;
}
}
//return $this->render('CNAMCMSBundle:Default:profile.html.twig', array(
//'search' => $search,
//'b_search'=>$b_search
// ));
}
return array('form'=>$form->createView());
}
/**
* #Route("/admin")
* #Template()
*/
public function adminAction()
{
return $this->render('CNAMCMSBundle:Default:admin.html.twig', array());
}
/**
* #Route("/admin/gestEtat",name="gestEtat")
* #Template()
*/
public function gestEtatAction()
{
return $this->render('CNAMCMSBundle:Default:gestEtat.html.twig', array());
}
}
<?php
namespace CNAM\CMSBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* user
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class user implements UserInterface
{
/**
* #var integer
*#Assert\NotBlank()
* #ORM\Column(name="id", type="integer")
* #ORM\Id
*/
private $id;
/**
* #var string
*#Assert\NotBlank()
* #ORM\Column(name="password", type="string", length=40)
*/
private $password;
/*
* #ORM\ManyToOne(targetEntity="profil" , inversedBy="users")
* #ORM\JoinColumn(name="id_profil", referencedColumnName="id_profil")
*/
private $profil;
public function __construct()
{
$this->profil = new ArrayCollection();
}
/**
* #var boolean
*
* #ORM\Column(name="etat", type="boolean")
*/
private $etat;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set id
*
* #param integer $id
* #return user
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Set password
*
* #param string $password
* #return user
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set etat
*
* #param boolean $etat
* #return user
*/
public function setEtat($etat)
{
$this->etat = $etat;
return $this;
}
/**
* Get etat
*
* #return boolean
*/
public function getEtat()
{
return $this->etat;
}
/**
* Get profil
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getProfil()
{
return $this->profil;
}
/**
* Add profil
*
* #param \CNAM\CMSBundle\Entity\user $profil
* #return user
*/
public function addProfil(\CNAM\CMSBundle\Entity\profil $profil)
{
$this->profil[] = $profil;
return $this;
}
/**
* Remove profil
*
* #param \CNAM\CMSBundle\Entity\profil $profil
*/
public function removeProfil(\CNAM\CMSBundle\Entity\profil $profil)
{
$this->profil->removeElement($profil);
}
public function getUsername()
{
return $this->id;
}
public function getRoles()
{
return array('ROLE_USER');
}
public function getSalt()
{
return null;
}
public function eraseCredentials()
{
}
public function equals(UserInterface $user)
{
return $user->getId() == $this->getId();
}
}
Related
I've been having trouble implementing Symfony's Security features in my project. I have configured my Security.yaml and created a securityController , my Userclass implements userInterface , and from what I can see on the docs I haven't missed anything out. My form renders fine, and I can input my username and password, but when I submit valid credentials it just refreshes the page. Profiler showed that no SQL queries had been made, and despite me configuring authenticationUtils to display errors (as per the tutorial on the docs) nothing is displayed.
Security.yaml
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
encoders:
App\Entity\User: sha256
providers:
in_memory: { memory: ~ }
main_db_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
# anonymous: true
pattern: ^/$ #test
form_login:
login_path: login
check_path: login
csrf_token_generator: security.csrf.token_manager
provider: main_db_provider
# activate different ways to authenticate
# http_basic: true
# https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
# form_login: true
# https://symfony.com/doc/current/security/form_login_setup.html
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/$, roles: ROLE_USER }
Security Controller
<?php
// src/Controller/SecurityController.php
namespace App\Controller;
use App\Entity\User;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends Controller
{
/**
* #Route("/login", name="login")
*/
public function login(Request $request, AuthenticationUtils $authenticationUtils)
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('ad-lotto-theme/login.html.twig', array(
'last_username' => $lastUsername,
'error' => $error,
));
}
}
User class
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
* #UniqueEntity("email", message="This email is already in use.")
* #UniqueEntity("username", message="This username is already in use")
*/
class User implements UserInterface, \Serializable
{
/**
* #ORM\Column(name="roles",type="string", length=255)
*/
private $roles;
/**
* #ORM\Column(name="salt",type="string", length=255)
*/
private $salt = "saltyboye";
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(name="username",type="string", length=255, unique=true)
*/
private $username;
/**
* #ORM\Column(name = "password", type="string", length=255)
*/
private $password;
/**
* #ORM\Column(name="email", type="string", length=255, unique=true)
*/
private $email;
/**
* #ORM\Column(type="datetime")
*/
private $registeredOn;
/**
* #ORM\Column(type="integer", nullable=true)
*/
private $referrer;
/**
* #ORM\Column(type="smallint")
*/
private $entries;
/**
* #ORM\Column(type="string", length=3)
*/
private $currency;
/** #see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->registeredOn,
$this->id,
$this->email,
$this->username,
$this->password,
$this->roles,
$this->referrer,
$this->currency,
$this->entries,
$this->salt));
// see section on salt below
// ,
}
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
// see section on salt below
// $this->salt
) = unserialize($serialized, array('allowed_classes' => false));
}
public function eraseCredentials()
{
}
public function getRoles()
{
return array("ROLE_USER");
}
public function getSalt()
{
return $this->salt;
}
public function getId()
{
return $this->id;
}
public function getUsername(): ?string
{
return $this->username;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getRegisteredOn(): ?\DateTimeInterface
{
return $this->registeredOn;
}
public function setRegisteredOn(\DateTimeInterface $registeredOn): self
{
$this->registeredOn = $registeredOn;
return $this;
}
public function getReferrer(): ?interedThisWeek
{
return $this->referrer;
}
public function setReferrer(?int $referrer): self
{
$this->referrer = $referrer;
return $this;
}
public function getEntries(): ?bool
{
return $this->entries;
}
public function setEntries(bool $entries): self
{
$this->entries = $entries;
return $this;
}
public function setCurrency(bool $currency): self
{
$this->currency = $currency;
return $this;
}
public function getCurrency(): ?bool
{
return $this->currency;
}
}
that salt is temporary, don't worry :) I haven't figured out how to implement SHA256 yet, but I needed to fill the field in the db :)
I'm assuming you follow this official tutorial: How to Build a Traditional Login Form
First of all your firewall configured to only 1 URI - / because of regex ^/$, so login form and other routes are not under the firewall.
Try to follow the tutorial from start to end just as it says there, make sure everything works and only then make changes.
I have a Invalid credentials error when I'm trying to load my user form the database.
Here is my security.yml
security:
providers:
database:
entity: { class: AppBundle\Entity\User, property: username }
encoders:
AppBundle\Entity\User: plaintext
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
# pattern: ^/
form_login:
login_path: /login
check_path: /login_check
# default_target_path: /admin
provider: database
logout:
path: /logout
target: /login
My User Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
*/
class User implements UserInterface
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", unique=true)
*/
private $username;
/**
* #ORM\Column(type="string")
*/
private $password;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* Returns the password used to authenticate the user.
*
* This should be the encoded password. On authentication, a plain-text
* password will be salted, encoded, and then compared to this value.
*
* #return string The password
*/
public function getPassword()
{
return $this->password;
}
/**
* Set password
*
* #param string $password
*
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Returns the salt that was originally used to encode the password.
*
* This can return null if the password was not encoded using a salt.
*
* #return string|null The salt
*/
public function getSalt()
{
}
/**
* Returns the username used to authenticate the user.
*
* #return string The username
*/
public function getUsername()
{
return $this->getUsername();
}
/**
* Set username
*
* #param string $username
*
* #return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
// TODO: Implement eraseCredentials() method.
}
/**
* Returns the roles granted to the user.
*
* <code>
* public function getRoles()
* {
* return array('ROLE_USER');
* }
* </code>
*
* Alternatively, the roles might be stored on a ``roles`` property,
* and populated in any number of different ways when the user object
* is created.
*
* #return (Role|string)[] The user roles
*/
public function getRoles()
{
// TODO: Implement getRoles() method.
}
}
My Controllers:
/**
* #Route("/login", name="login")
*/
public function loginAction(Request $request)
{
$authenticationUtils = $this->get('security.authentication_utils');
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
$form = $this->createForm(LoginType::class, array(
'_username' => $lastUsername,
));
return $this->render(':back/security:login.html.twig', array(
'error' => $error,
'form' => $form->createView(),
));
}
/**
* #Route("/login_check", name="login_check")
*/
public function loginCheckAction(){}
I don't understand why it does not work. I have tried to follow the documentation and make it very simple.
The user is in my database and the password is plaintext.
What did I do wrong?
I'm trying to follow the documentation but can't get it to work. I keep getting "Bad credentials" when trying to use the login form.
Here is my security.yml file
security:
encoders:
MyCompany\MyPoroject\UserBundle\Entity\User:
algorithm: sha1
encode_as_base64: false
iterations: 1
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
administrators:
entity: { class: MyCompanyMyProjectUserBundle:User, property: username }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
pattern: ^/
anonymous: ~
form_login:
login_path: login
check_path: login_check
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
This is the code i've used to create some dummy users
$factory = $this->get('security.encoder_factory');
$user = new User;
$encoder = $factory->getEncoder($user);
$password = $encoder->encodePassword('testing', $user->getSalt());
$user->setPassword($password)
->setEmail('test#gmail.com')
->setUsername('testing');
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
Here is my User class
class User implements UserInterface, \Serializable
{
private $id;
private $username;
private $salt;
private $password;
private $email;
private $isActive;
public function __construct()
{
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}
/**
* Returns the roles granted to the user.
*
* <code>
* public function getRoles()
* {
* return array('ROLE_USER');
* }
* </code>
*
* Alternatively, the roles might be stored on a ``roles`` property,
* and populated in any number of different ways when the user object
* is created.
*
* #return Role[] The user roles
*/
public function getRoles()
{
return ['ROLE_USER'];
}
/**
* Returns the password used to authenticate the user.
*
* This should be the encoded password. On authentication, a plain-text
* password will be salted, encoded, and then compared to this value.
*
* #return string The password
*/
public function getPassword()
{
$this->password;
}
/**
* Returns the salt that was originally used to encode the password.
*
* This can return null if the password was not encoded using a salt.
*
* #return string|null The salt
*/
public function getSalt()
{
$this->salt;
}
/**
* Returns the username used to authenticate the user.
*
* #return string The username
*/
public function getUsername()
{
return $this->username;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
* #return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Set salt
*
* #param string $salt
* #return User
*/
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
/**
* Set password
*
* #param string $password
* #return User
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Set email
*
* #param string $email
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set is_active
*
* #param boolean $isActive
* #return User
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get is_active
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* (PHP 5 >= 5.1.0)<br/>
* String representation of object
* #link http://php.net/manual/en/serializable.serialize.php
* #return string the string representation of the object or null
*/
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->salt,
$this->password,
));
}
/**
* (PHP 5 >= 5.1.0)<br/>
* Constructs the object
* #link http://php.net/manual/en/serializable.unserialize.php
* #param string $serialized <p>
* The string representation of the object.
* </p>
* #return void
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->salt,
$this->password,
) = unserialize($serialized);
}
/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
}
}
My Security controller
class SecurityController extends Controller
{
public function loginAction(Request $request)
{
$session = $request->getSession();
// get the login error if there is one
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(
SecurityContext::AUTHENTICATION_ERROR
);
} else {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render(
'MyCompanyMyProjectUserBundle:Security:login.html.twig',
array(
// last username entered by the user
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
)
);
}
public function adminAction()
{
return $this->render('MyCompanyMyProjectUserBundle:Security:admin.html.twig');
}
}
This is the record in the database i'm attempting to login with using testing as both the username and password.
id: 3
username(25): testing
salt(32): 87a449194ebfe80bfa9f59da53dab0ea
password(64): dc724af18fbdd4e59189f5fe768a5f8311527050
email(60): test#gmail.com
Probably you missed return statement in getSalt() and getPassword() methods
I'm trying since 3 hours to install and configure FOSuser, which many developpers adviced me to use it.I wanted actually to make a normal login form without to use FOS but I had a lot of problems.I followed all steps in the documentation. the installation was ok , the configuration also but everytime when I try to log in , it shows "Bad credentials".So i find somehow this command that I executed :php app/console fos:user:create i give name-email-password. it work somehow but only with what i write, I mean when I register user in my registration form and try to log in it shows "Bad credentials".I hope that I was clear else please tell me what do you need to know
Here are my Users.php where i have all my users info to login...
namespace test\indexBundle\Document;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
*
* #MongoDB\Document
*/
class Users extends BaseUser
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
*/
protected $userId;
/**
* #MongoDB\String
*/
protected $userEmail;
/**
* #MongoDB\String
*/
protected $userPassword;
/**
* #MongoDB\String
*/
protected $salt;
/**
* #MongoDB\Int
*/
protected $isActive;
public function __construct()
{
parent::__construct();
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}
/**
* Set id
*
* #param id $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Get id
*
* #return id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set userId
*
* #param string $userId
*/
public function setUserId()
{
$this->userId = $this->salt;
}
/**
* Get userId
*
* #return string $userId
*/
public function getUserId()
{
return $this->userId;
}
/**
* Set userName
*
* #param string $userName
*/
public function setUserName($userName)
{
$this->userName = $userName;
}
/**
* Get userName
*
* #return string $userName
*/
public function getUserName()
{
return $this->username;
}
/**
* Set userEmail
*
* #param string $userEmail
*/
public function setUserEmail($userEmail)
{
$this->userEmail = $userEmail;
}
/**
* Get userEmail
*
* #return string $userEmail
*/
public function getUserEmail()
{
return $this->userEmail;
}
/**
* Set userPassword
*
* #param string $userPassword
*/
public function setPassword($userPassword)
{
$this->userPassword = $userPassword;
}
/**
* Get userPassword
*
* #return string $userPassword
*/
public function getPassword()
{
return $this->userPassword;
}
/**
* #inheritDoc
*/
public function getSalt()
{
return '';
}
/**
* #inheritDoc
*/
public function getRoles()
{
return array('ROLE_USER');
}
/**
* #inheritDoc
*/
public function eraseCredentials()
{
}
/**
* #see \Serializable::serialize()
*/
public function serialize()
{
return serialize(array(
$this->id
));
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id
) = unserialize($serialized);
}
}
and here my security.yml:
jms_security_extra:
secure_all_services: false
expressions: true
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
test\indexBundle\Document\Users:
algorithm: sha1
encode_as_base64: false
iterations: 1
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
anonymous: true
form_login:
check_path: /login_check
login_path: /login
provider: fos_userbundle
post_only: true
use_forward: false
username_parameter: email
password_parameter: password
failure_path: null
failure_forward: false
target_path_parameter: redirect_url
logout:
path: /logout
target: /blog
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
and login function:
public function loginAction()
{
$request = $this->getRequest();
$session = $request->getSession();
if ($this->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY'))
{
return $this->redirect($this->generateUrl('index_homepage'));
}
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR))
{
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
}
else
{
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render('indexBundle:index:logIn.html.twig', array(
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
));
}
I might be wrong but I think FOSUserBundle requires a user to be activated after it's been created if you use the form registration, it's send out and email with a link I believe. I think you can use app/console fos:user:activate to activate if there is no email.
I have a problem with the FOSUserBundle.
A know problem : 'Unrecognized field: usernameCanonical for symfony2 FosUserbundle' when I try a login
AND
on schema update I get this error:
Duplicate definition of column 'username' on entity 'Acme\ProjectBundle\Entity\User' in a field or discriminator column mapping.
I get this error ONLY IF I add the 'FOSUserBundle: ~' to settings of doctrine's mapping in the config.yml
I have tried a lot of solutions but I don't have resoved my problem :/
Please help me.
I have followed the FOS' team: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md
Before everything worked perfectly ...
I have Symfony 2.1.9
My config.yml:
doctrine:
dbal:
default_connection: default
connections:
default:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
service:
driver: "%database_driver2%"
host: "%database_host2%"
port: "%database_port2%"
dbname: "%database_name2%"
user: "%database_user2%"
password: "%database_password2%"
charset: UTF8
orm:
auto_generate_proxy_classes: "%kernel.debug%"
#auto_mapping: true
default_entity_manager: default
entity_managers:
default:
metadata_cache_driver: apc
result_cache_driver: apc
query_cache_driver: apc
connection: default
mappings:
FOSUserBundle: ~
AcmeProjectBundle: {type: yml, dir: Resources/config/doctrine/ } #also tried wit '~'
fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: main
user_class: Acme\ProjectBundle\Entity\User
My Acme\ProjectBundle\Entity\User.php:
namespace Acme\ProjectBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\User\UserInterface;
class User extends BaseUser implements UserInterface, \Serializable
{
const TYPE_ADMIN = 0;
const TYPE_USER = 2;
const TYPE_ARTIST = 3;
/**
* #var string $salt
*/
protected $salt;
/**
* #var boolean $is_active
*/
private $is_active;
protected $id;
private $name;
protected $username;
protected $email;
/**
* #var tinyint $type
*/
private $type;
protected $password;
private $description;
/**
* Get id
*
* #return integer
*/
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 type
*
* #param integer $type
* #return User
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return integer
*/
public function getType()
{
return $this->type;
}
/**
* Set description
*
* #param string $description
* #return User
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* 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 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;
}
public function isPasswordName()
{
return ($this->name != $this->password);
}
public function isPassUsername()
{
return ($this->password != $this->username);
}
/**
* #var \DateTime $date
*/
private $date;
/**
* Set date
*
* #param \DateTime $date
* #return User
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date
*
* #return \DateTime
*/
public function getDate()
{
return $this->date;
}
private $updateDate;
/**
* Set updateDate
*
* #param \DateTime $updateDate
* #return User
*/
public function setUpdateDate($updateDate)
{
$this->updateDate = $updateDate;
return $this;
}
/**
* Get updateDate
*
* #return \DateTime
*/
public function getUpdateDate()
{
return $this->updateDate;
}
public function setIsActive($value)
{
$this->is_active = $value;
return $this;
}
public function gettIsActive()
{
return $this->is_active;
return $this;
}
/**
* 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;
}
/**
* #inheritDoc
*/
public function eraseCredentials()
{
}
public function __construct()
{
parent::__construct();
$this->isActive = true;
$this->salt = md5(uniqid(null, true));
}
public function getRoles()
{
switch ($this->getType())
{
case 0:
return array('ROLE_ADMIN');
break;
case 1:
case 2:
case 3:
return array('ROLE_USER');
break;
}
}
/**
* #see \Serializable::serialize()
*/
public function serialize()
{
return serialize(array(
$this->id,
));
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
) = unserialize($serialized);
}
/**
* #var integer $first_login
*/
private $first_login;
/**
* Get is_active
*
* #return boolean
*/
public function getIsActive()
{
return $this->is_active;
}
/**
* Set first_login
*
* #param integer $firstLogin
* #return User
*/
public function setFirstLogin($firstLogin)
{
$this->first_login = $firstLogin;
return $this;
}
/**
* Get first_login
*
* #return integer
*/
public function getFirstLogin()
{
return $this->first_login;
}
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*/
private $userPoints;
/**
* #var integer $privacy
*/
private $privacy;
/**
* Set privacy
*
* #param integer $privacy
* #return User
*/
public function setPrivacy($privacy)
{
$this->privacy = $privacy;
return $this;
}
/**
* Get privacy
*
* #return integer
*/
public function getPrivacy()
{
return $this->privacy;
}
/**
* #var integer
*/
private $enable;
/**
* Set enable
*
* #param integer $enable
* #return User
*/
public function setEnable($enable)
{
$this->enable = $enable;
return $this;
}
/**
* Get enable
*
* #return integer
*/
public function getEnable()
{
return $this->enable;
}
}
My security.yml
security:
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
login_path: /login
use_forward: false
check_path: /login_check
csrf_provider: form.csrf_provider
logout: true
anonymous: true
providers:
fos_userbundle:
id: fos_user.user_provider.username
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
It seems your version of the FOSUserBundle is not good ... I had the same problem with a 1.3.* that I solved just changing this to version "~2.0#dev".
You can check this looking at your "fos_user" table ; if it just contains a single "id" field, your User entity is not extending the right "FOS\Entity\User" object ... try to upgrade your required version of the bundle in your "composer.json" and then rebuild your tables (below a full HARD rebuild - data are lost):
php app/console doctrine:schema:drop --force
php app/console doctrine:schema:create
If your "fos_user" table have all required fields, then you're good.
Review the docs on creating a use class: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md
Your User class should not be repeating all the properties (username etc) from the base class. It should only have the new properties like name and id.
And while you didn't show your doctrine mapping file, I'm guessing your probably duplicated everything in there is well? Only map the new properties.
In fact, i guess, you should have some piece of code on config.yml as
fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: main
user_class: Acme\ProjectBundle\Entity\User
and you should have no need to add sth. to orm settings for FOSUser.
orm:
auto_generate_proxy_classes: "%kernel.debug%"
#auto_mapping: true
default_entity_manager: default
entity_managers:
default:
// that's for APCu or APC
metadata_cache_driver: apc
result_cache_driver: apc
query_cache_driver: apc
in dev env APC disabled, that's why you get this error. You have to comment it for dev or enable cacheClassLoader
I had this trouble and applied PieroWbmstr's suggestion, and started using 2.0 instead of 1.3.6... with doctrine.orm.auto_mapping set to true in config.yml
Once I made the composer.json version switch and upgraded, my doctrine:schema:update instantly recognised the new fields as missing in the current database instance, and applied them.
The newer version of the user class within FOS/UserBundle doesn't seem to have any significant changes that would force the mapping to play nicely. Does anyone have an idea as to what the difference is in these two versions? Or more directly, why the older version somehow didn't let doctrine recognise it's xml mappings (hint: in both of my FOS/UserBundle versions, I had my local custom bundles set to use annotations).
Thanks