I've got an issue with Symfony 2.4(.4) that has been driving me nuts for 3 days.
I'm using FOSUserBundle and CouchDB to authenticate my users through a basic login form.
I've setup a firewall to protect the all site.
The logs show the authentication is successful but the session token is never set and thus Symfony brings me back to the login page. I know the authentication is successful because if I submit a wrong login/password I get an error message, so CouchDB is not an issue.
Here is what I've already done with no luck :
- upgraded symfony to the last version
- checked session : OK (I'm able to manually set/get a session variable) through all pages
- checked that token is set in Symfony\Component\Security\Http\Firewall\ContextListener::onKernelResponse() : OK
- modified NativeSessionStorage:regenerate() to avoid session regeneration : no effet
- add a context variable in my firewall : no effet
- cleared all cookies : no effect
- put multiple breakpoints on every Listner/Handler/Dispatcher/ I could think of : found nothing
The only thing that allows me to see my main page is to comment the whole content of Fos\UserBundle\Model\User::serialize() but then of course I'm not even authenticated anonymously so I can't access any user information.
I've been playing around with Symfony for a few years now and even if I'm not an expert I've never had such a blocking issue. I'm SURE this is a stupid mistake I've made that is under my nose but I just can't find it.
Here is my security.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
anonymous: ~
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
logout: true
anonymous: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/bo, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
- { path: ^/, role: ROLE_USER }
Here is the log file
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelRequest". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Bundle\FrameworkBundle\EventListener\SessionListener::onKernelRequest". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\FragmentListener::onKernelRequest". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\RouterListener::onKernelRequest". [] []
[2014-04-28 19:37:43] request.INFO: Matched route "fos_user_security_check" (parameters: "_controller": "FOS\UserBundle\Controller\SecurityController::checkAction", "_route": "fos_user_security_check") [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelRequest". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.request" to listener "FOS\RestBundle\EventListener\BodyListener::onKernelRequest". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\Security\Http\Firewall::onKernelRequest". [] []
[2014-04-28 19:37:43] security.INFO: User "user3@user.fr" has been authenticated successfully [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "security.interactive_login" to listener "FOS\UserBundle\EventListener\LastLoginListener::onSecurityInteractiveLogin". [] []
[2014-04-28 19:37:43] event.DEBUG: Listener "Symfony\Component\Security\Http\Firewall::onKernelRequest" stopped propagation of the event "kernel.request". [] []
[2014-04-28 19:37:43] event.DEBUG: Listener "Symfony\Bundle\AsseticBundle\EventListener\RequestListener::onKernelRequest" was not called for event "kernel.request". [] []
[2014-04-28 19:37:43] event.DEBUG: Listener "Symfony\Component\HttpKernel\EventListener\ErrorsLoggerListener::injectLogger" was not called for event "kernel.request". [] []
[2014-04-28 19:37:43] event.DEBUG: Listener "Symfony\Component\HttpKernel\EventListener\ErrorsLoggerListener::injectLogger" was not called for event "kernel.request". [] []
[2014-04-28 19:37:43] event.DEBUG: Listener "Stof\DoctrineExtensionsBundle\EventListener\BlameListener::onKernelRequest" was not called for event "kernel.request". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\Security\Http\Firewall\ContextListener::onKernelResponse". [] []
[2014-04-28 19:37:43] security.DEBUG: Write SecurityContext in the session [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\HttpKernel\EventListener\ResponseListener::onKernelResponse". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\Security\Http\RememberMe\ResponseListener::onKernelResponse". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.response" to listener "Sensio\Bundle\FrameworkExtraBundle\EventListener\HttpCacheListener::onKernelResponse". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelResponse". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.response" to listener "Symfony\Bundle\WebProfilerBundle\EventListener\WebDebugToolbarListener::onKernelResponse". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.response" to listener "Symfony\Component\HttpKernel\EventListener\StreamedResponseListener::onKernelResponse". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.finish_request" to listener "Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelFinishRequest". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.finish_request" to listener "Symfony\Component\HttpKernel\EventListener\RouterListener::onKernelFinishRequest". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.finish_request" to listener "Symfony\Component\Security\Http\Firewall::onKernelFinishRequest". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.terminate" to listener "Symfony\Bundle\SwiftmailerBundle\EventListener\EmailSenderListener::onTerminate". [] []
[2014-04-28 19:37:43] event.DEBUG: Notified event "kernel.terminate" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelTerminate". [] []
[2014-04-28 19:37:44] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelRequest". [] []
[2014-04-28 19:37:44] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Bundle\FrameworkBundle\EventListener\SessionListener::onKernelRequest". [] []
[2014-04-28 19:37:44] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\FragmentListener::onKernelRequest". [] []
[2014-04-28 19:37:44] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\RouterListener::onKernelRequest". [] []
[2014-04-28 19:37:44] request.INFO: Matched route "ocp_front_default_index" (parameters: "_controller": "OCP\FrontBundle\Controller\DefaultController::indexAction", "_route": "ocp_front_default_index") [] []
[2014-04-28 19:37:44] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelRequest". [] []
[2014-04-28 19:37:44] event.DEBUG: Notified event "kernel.request" to listener "FOS\RestBundle\EventListener\BodyListener::onKernelRequest". [] []
[2014-04-28 19:37:44] event.DEBUG: Notified event "kernel.request" to listener "Symfony\Component\Security\Http\Firewall::onKernelRequest". [] []
[2014-04-28 19:37:44] security.DEBUG: Read SecurityContext from the session [] []
[2014-04-28 19:37:44] security.DEBUG: Reloading user from user provider. [] []
[2014-04-28 19:37:44] security.WARNING: Username "" could not be found. [] []
[2014-04-28 19:37:44] security.INFO: Populated SecurityContext with an anonymous Token [] []
Here is the User.php
<?php
namespace OCP\BackBundle\CouchDocument;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ODM\CouchDB\Mapping\Annotations as CouchDB;
/**
* User
*
* @CouchDB\Document
*/
class User extends BaseUser
{
/**
* @var integer
*
* @CouchDB\Id
*/
protected $id;
/**
* @var string
*
* @CouchDB\Field(type="string")
* @Assert\NotBlank(message="Vous devez spécifier un prénom.")
* @Assert\Length(
* min = "2",
* max = "20",
* minMessage = "Le prénom doit faire au moins {{ limit }} caractères.",
* maxMessage = "Le prénom ne doit pas faire plus de {{ limit }} caractères."
* )
*/
protected $firstname;
/**
* @var string
*
* @CouchDB\Field(type="string")
* @Assert\NotBlank(message="Vous devez spécifier un nom.")
* @Assert\Length(
* min = "2",
* max = "20",
* minMessage = "Le nom doit faire au moins {{ limit }} caractères.",
* maxMessage = "Le nom ne doit pas faire plus de {{ limit }} caractères."
* )
*/
protected $lastname;
/**
* @var string
*
* @CouchDB\Field(type="string")
* @Assert\Length(
* min = "10",
* max = "10",
* minMessage = "Le numéro de téléphone doit faire au moins {{ limit }} chiffres.",
* maxMessage = "Le numéro de téléphone ne peut pas faire plus de {{ limit }} chiffres."
* )
* @Assert\Regex(
* pattern="/^[0][0-9]{9}$/",
* match=true,
* message="Le numéro de téléphone ne peut contenir des chiffres."
* )
*/
protected $phoneNumber;
/**
* @var string
*
* @CouchDB\Field(type="string")
* @Assert\Length(
* min = "1",
* max = "10",
* minMessage = "Le code commercial doit faire au moins {{ limit }} chiffres.",
* maxMessage = "Le code commercial ne peut pas faire plus de {{ limit }} chiffres."
* )
*/
protected $commercialCode;
/**
* @var string
*
* @CouchDB\Field(type="string")
*/
protected $tmpPassword;
/**
* @var \DateTime
*
* @Gedmo\Timestampable(on="create")
* @CouchDB\Field(type="datetime")
*/
private $creationDate;
/**
* @var \DateTime
*
* @Gedmo\Timestampable(on="update")
* @CouchDB\Field(type="datetime")
*/
private $updateDate;
/**
* @var User $creationUser
*
* @Gedmo\Blameable(on="create")
* @CouchDB\ReferenceOne(targetDocument="User")
*/
private $creationUser;
/**
* @var User $updateUser
*
* @Gedmo\Blameable(on="update")
* @CouchDB\ReferenceOne(targetDocument="User")
*/
private $updateUser;
/**
* @CouchDB\ReferenceOne(targetDocument="DC")
*/
private $dc;
/**
* @CouchDB\ReferenceOne(targetDocument="REC")
*/
private $rec;
/**
* @CouchDB\ReferenceOne(targetDocument="DVOC")
*/
private $dvoc;
/**
* @CouchDB\ReferenceOne(targetDocument="BRanch")
*/
private $branch;
/**
* @CouchDB\ReferenceOne(targetDocument="CommercialArea")
*/
private $commercialArea;
public function __construct()
{
parent::__construct();
// your own logic
$this->roles = ["ROLE_USER"];
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* 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 phoneNumber
*
* @param string $phoneNumber
* @return User
*/
public function setPhoneNumber($phoneNumber)
{
$this->phoneNumber = $phoneNumber;
return $this;
}
/**
* Get phoneNumber
*
* @return string
*/
public function getPhoneNumber()
{
return $this->phoneNumber;
}
/**
* Set creationDate
*
* @param \DateTime $creationDate
* @return User
*/
public function setCreationDate($creationDate)
{
$this->creationDate = $creationDate;
return $this;
}
/**
* Get creationDate
*
* @return \DateTime
*/
public function getCreationDate()
{
return $this->creationDate;
}
/**
* 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;
}
/**
* Set commercialCode
*
* @param string $commercialCode
* @return User
*/
public function setCommercialCode($commercialCode)
{
$this->commercialCode = $commercialCode;
return $this;
}
/**
* Get commercialCode
*
* @return string
*/
public function getCommercialCode()
{
return $this->commercialCode;
}
/**
* Set dc
*
* @param \OCP\BackBundle\CouchDocument\DC $dc
* @return User
*/
public function setDc(\OCP\BackBundle\CouchDocument\DC $dc)
{
$this->dc = $dc;
return $this;
}
/**
* Get dc
*
* @return \OCP\BackBundle\CouchDocument\DC
*/
public function getDc()
{
return $this->dc;
}
/**
* Set rec
*
* @param \OCP\BackBundle\CouchDocument\REC $rec
* @return User
*/
public function setRec(\OCP\BackBundle\CouchDocument\REC $rec)
{
$this->rec = $rec;
return $this;
}
/**
* Get rec
*
* @return \OCP\BackBundle\CouchDocument\REC
*/
public function getRec()
{
return $this->rec;
}
/**
* Set dvoc
*
* @param \OCP\BackBundle\CouchDocument\DVOC $dvoc
* @return User
*/
public function setDvoc(\OCP\BackBundle\CouchDocument\DVOC $dvoc)
{
$this->dvoc = $dvoc;
return $this;
}
/**
* Get dvoc
*
* @return \OCP\BackBundle\CouchDocument\DVOC
*/
public function getDvoc()
{
return $this->dvoc;
}
/**
* Set branch
*
* @param \OCP\BackBundle\CouchDocument\Branch $branch
* @return User
*/
public function setBranch(\OCP\BackBundle\CouchDocument\Branch $branch)
{
$this->branch = $branch;
return $this;
}
/**
* Get branch
*
* @return \OCP\BackBundle\CouchDocument\Branch
*/
public function getBranch()
{
return $this->branch;
}
/**
* Set creationUser
*
* @param \OCP\BackBundle\CouchDocument\User $creationUser
* @return User
*/
public function setCreationUser(\OCP\BackBundle\CouchDocument\User $creationUser = null)
{
$this->creationUser = $creationUser;
return $this;
}
/**
* Get creationUser
*
* @return \OCP\BackBundle\CouchDocument\User
*/
public function getCreationUser()
{
return $this->creationUser;
}
/**
* Set updateUser
*
* @param \OCP\BackBundle\CouchDocument\User $updateUser
* @return User
*/
public function setUpdateUser(\OCP\BackBundle\CouchDocument\User $updateUser = null)
{
$this->updateUser = $updateUser;
return $this;
}
/**
* Get updateUser
*
* @return \OCP\BackBundle\CouchDocument\User
*/
public function getUpdateUser()
{
return $this->updateUser;
}
/**
* Set commercialArea
*
* @param \OCP\BackBundle\CouchDocument\CommercialArea $commercialArea
* @return User
*/
public function setCommercialArea(\OCP\BackBundle\CouchDocument\CommercialArea $commercialArea)
{
$this->commercialArea = $commercialArea;
return $this;
}
/**
* Get commercialArea
*
* @return \OCP\BackBundle\CouchDocument\CommercialArea
*/
public function getCommercialArea()
{
return $this->commercialArea;
}
/**
* Set tmpPassword
*
* @param string $tmpPassword
* @return User
*/
public function setTmpPassword($tmpPassword)
{
$this->tmpPassword = $tmpPassword;
return $this;
}
/**
* Get tmpPassword
*
* @return string
*/
public function getTmpPassword()
{
return $this->tmpPassword;
}
public function getWSUser()
{
return array(
"id" => $this->id,
"firstname" => $this->firstname,
"lastname" => $this->lastname,
"email" => $this->email,
"phone_number" => $this->phoneNumber,
"commercial_code" => $this->commercialCode,
"dc" => $this->dc->getId(),
"rec" => (!$this->rec) ? $this->rec : $this->rec->getId(),
"dvoc" => (!$this->dvoc) ? $this->dvoc : $this->dvoc->getId(),
"branch" => (!$this->branch) ? $this->branch : $this->branch->getId(),
"commercial_area" => (!$this->commercialArea) ? $this->commercialArea : $this->commercialArea->getId(),
"creation_date" => $this->creationDate,
"update_date" => $this->updateDate,
"creation_user" => $this->creationUser->getId(),
"update_user" => (!$this->updateUser) ? $this->updateUser : $this->updateUser->getId(),
);
}
}