security - Symfony2 User roles vanish between Listener and UserProvider -


i'm having trouble (again) security component of symfony2.

first thing first, there severals objects involved in process of authentication :

  1. securityfactoryinterface
  2. abstractauthenticationlistener
  3. authenticationproviderinterface
  4. custom token (inherits abstracttoken)
  5. userproviderinterface

flow

if understand well, aim of security factory configure custom authentication.

the listener conductor of authentication. throught attemptauthentication method captures form submission (containing user's credentials) , tries authenticate user. inside method, listener create abstracttoken , pass token authenticate method of authenticationprovider.

after that, authenticationprovider calls userprovider retrieve users data webservice or database etc...

once userprovider did magic, returns user object authenticationprovider.

the authenticationprovider creates new token filled user retrieved userprovider , retunrs listener.

after getting new token, listener unknown magic (i think sets token security context i'm not sure).

problem

at each steps did var_dump of user object. roles set in every steps except in "final steps": in listener.

when listener retrieve authenticated token userprovider, user's roles empty. can't figure out why...

securityfactory

class companyfactory implements securityfactoryinterface {     public function create(containerbuilder $container, $id, $config, $userprovider, $defaultentrypoint)     {         $providerid = 'security.authentication.provider.company.'.$id;         $container             ->setdefinition($providerid, new definitiondecorator('company.security.authentication.provider'))             ->replaceargument(0, new reference($userprovider));          $listenerid = 'security.authentication.listener.company.'.$id;         $listener = $container->setdefinition($listenerid, new definitiondecorator('company.security.authentication.listener'));          return array($providerid, $listenerid, $defaultentrypoint);     }      public function getposition()     {         return 'pre_auth';     }      public function getkey()     {         return 'company';     }      public function addconfiguration(nodedefinition $node)     {     } } 

listener

class companylistener extends abstractauthenticationlistener {     // custructor stuff removed      protected function requiresauthentication(request $request)     {         if ($this->options['post_only'] && !$request->ismethod('post'))         {             return false;         }          return parent::requiresauthentication($request);     }      protected function attemptauthentication(request $request)     {         $username = trim($request->get($this->options['username_parameter'], null, true));         $password = $request->get($this->options['password_parameter'], null, true);         $ip       = $request->getclientip();          $request->getsession()->set(securitycontextinterface::last_username, $username);          $authtoken = $this->authenticationmanager->authenticate(new companyusertoken($username, $password, $ip));          return $authtoken;     } } 

authenticationprovider

class companyprovider implements authenticationproviderinterface {     private $userprovider;      public function __construct(userproviderinterface $userprovider)     {         $this->userprovider = $userprovider;     }      public function authenticate(tokeninterface $token)     {         $user = $this->userprovider->loaduserbyusernamepassword($token->user, $token->getpassword(), $token->getip());          $authenticatedtoken = new companyusertoken($user->getusername(), $user->getpassword(), $user->getip(), $user->getroles());         $authenticatedtoken->setuser($user);          return $authenticatedtoken;     }      public function supports(tokeninterface $token)     {         return $token instanceof companyusertoken;     } } 

custom token

class companyusertoken extends abstracttoken {     private $password;     private $ip;      public function __construct($username, $password, $ip, array $roles = array())     {         parent::__construct($roles);          $this->password = $password;         $this->user = $username;         $this->ip = $ip;          // if user has roles, consider authenticated         $this->setauthenticated(count($roles) > 0);     }      public function getcredentials()     {         return '';     }      public function getpassword()     {         return $this->password;     }      public function getip()     {         return $this->ip;     } } 

user provider

class companyuserprovider implements userproviderinterface {     private $documentmanager;      public function __construct($doctrinemongodb)     {         $this->doctrinemongodb = $doctrinemongodb;     }      public function loaduserbyusername($username)     {         // not used needed interface     }      public function loaduserbyusernamepassword($username, $password, $ip)     {         // magic, retrieve user datas db.          return $user;     }      public function refreshuser(userinterface $user)     {         // same thing above method         return $refresheduser;     }      public function supportsclass($class)     {         return $class === 'company\userbundle\document\user';     } } 

service.yml

parameters:      security.authentication.handler.class: company\userbundle\security\authentication\handler\compnayauthenticationhandler     company_user_provider.class: company\userbundle\security\user\companyuserprovider  services:     security.authentication.handler:         class: %security.authentication.handler.class%         public: false         arguments: [@router, @security.http_utils]      company.security.authentication.provider:         class: company\userbundle\security\authentication\provider\companyprovider         arguments: [@company_user_provider]      company.security.authentication.listener:         class: company\userbundle\security\firewall\companylistener         arguments: [@security.context, @security.authentication.manager, @security.authentication.session_strategy, @security.http_utils, "company", @security.authentication.handler, @security.authentication.handler, {}, @logger, @event_dispatcher, @user.service.captcha]      company_user_provider:         class: %company_user_provider.class%         arguments: [@doctrine_mongodb]      user.service.captcha:         class: company\userbundle\services\captchaservice         arguments: [@form.factory] 

security.yml

jms_security_extra:     secure_all_services: false     expressions: true  security:     encoders:         company\userbundle\document\user: plaintext      role_hierarchy:         role_vip_user:    role_user         role_admin:       [role_user, role_vip_user]      providers:         webservice:             id: company_user_provider      firewalls:           company_secured:             pattern: ^/             company: true             anonymous: true             form_login:                 login_path: login                 check_path: login_check                 post_only: true                 use_referer: false                 success_handler: security.authentication.handler                 failure_handler: security.authentication.handler             logout:                  path: /logout                 target: login      access_control:         - { path: ^/admin, role: role_admin } 

update

here var_dumps explain problem :

userprovider

var_dump($user);

object(company\userbundle\document\user)[142]   protected 'username' => string 'supacoco' (length=13)   protected 'roles' =>      array (size=1)       0 => string 'role_admin' (length=10) 

authenticationprovider

var_dump($authenticatedtoken->getuser());

object(company\userbundle\document\user)[142]   protected 'username' => string 'supacoco' (length=13)   protected 'roles' =>      array (size=1)       0 => string 'role_admin' (length=10) 

listener

var_dump($authtoken->getuser());

object(company\userbundle\document\user)[142]   protected 'username' => string 'supacoco' (length=13)   protected 'roles' =>      array (size=0)       empty 

after digging lot, discovered "authenticationprovidermanager", after authenticating token, calls default user's method "erasecredentials".

the code below explains why user loses his/her roles after logging in.

public function erasecredentials() {     $this->roles = array(); } 

Comments

Popular posts from this blog

php - Calling a template part from a post -

Firefox SVG shape not printing when it has stroke -

How to mention the localhost in android -