title: Symfony2 - Wrong Token after authentication
body: <p>I am new to Symfony2 and facing an issue since a week as I need to implement custom authentication. I managed to get create everything i.e. token, listener, provider, factory, user provider etc. My issue is that after authentication, I unable to see correct token. What I think that the UsernamePasswordProvider (provided by symfony2) still runs after authentication and refreshUser in user provider shows me the wrong token. I try to search almost everywhere but unable to fix this issue. Need some help/hint on this if anybody knows. Thanks.</p>
  
  <p>Here is the image (<a href="http://tinypic.com/r/33bl5l0/5" rel="nofollow">http://tinypic.com/r/33bl5l0/5</a>) of wrong token. This should be <strong>ADWSUserToken</strong></p>
  
  <p>Below is the code. I am using Symfony 2.2.0</p>
  
  <p><strong>ADWSUserToken.php</strong></p>
  
  <pre><code>namespace StudentIntranet\GenericBundle\Security\Authentication\Token;
  
  use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
  
  class ADWSUserToken extends AbstractToken
  {
      public $userObjectType = "";
      public $password = "";
  
      public function getCredentials()
      {
          return '';
      }
  }
  </code></pre>
  
  <p><strong>ADWSListener.php</strong></p>
  
  <pre><code>namespace StudentIntranet\GenericBundle\Security\Firewall;
  
  use Symfony\Component\HttpFoundation\Response;
  use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  use Symfony\Component\Security\Http\Firewall\ListenerInterface;
  use Symfony\Component\Security\Http\HttpUtils;
  use Symfony\Component\Security\Core\Exception\AuthenticationException;
  use Symfony\Component\Security\Core\SecurityContextInterface;
  use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
  
  use StudentIntranet\GenericBundle\Security\Authentication\Token\ADWSUserToken;
  
  class ADWSListener implements ListenerInterface
  {
      protected $securityContext;
      protected $authenticationManager;
      protected $providerKey;
  
      public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager)
      {
          $this-&gt;securityContext = $securityContext;
          $this-&gt;authenticationManager = $authenticationManager;
      }
  
      public function handle(GetResponseEvent $event)
      {
          $httpUtils = new HttpUtils();
          $request = $event-&gt;getRequest();
          $form = $request-&gt;request-&gt;get('form');
          foreach (array('_token', 'username', 'password') as $val) {
              $$val = isset($form[$val]) ? $form[$val] : "";
          }
          $remember_me = isset($form['remember_me']) ? $form['remember_me'] : "Off";
  
          if (!$username || !$password) {
              return;
          }
  
          $token = new ADWSUserToken();
          $token-&gt;setUser($username);
          $token-&gt;password = $password;
  
          try {
              $authToken = $this-&gt;authenticationManager-&gt;authenticate($token);
              $this-&gt;securityContext-&gt;setToken($authToken);
          } catch (AuthenticationException $failed) {
              $this-&gt;securityContext-&gt;setToken(null);
              $event-&gt;setResponse($httpUtils-&gt;createRedirectResponse($request, '/login'));
              return;
          }
  
          // By default deny authorization
  //        $response = new Response('NO');
  //        $response-&gt;setStatusCode(403);
  //        $event-&gt;setResponse($response);
      }
  }
  </code></pre>
  
  <p><strong>ADWSProvider.php</strong></p>
  
  <pre><code>namespace StudentIntranet\GenericBundle\Security\Authentication\Provider;
  
  use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
  use Symfony\Component\Security\Core\User\UserProviderInterface;
  use Symfony\Component\Security\Core\Exception\AuthenticationException;
  use Symfony\Component\Security\Core\Exception\NonceExpiredException;
  use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  
  use StudentIntranet\GenericBundle\Security\Authentication\Token\ADWSUserToken;
  
  class ADWSProvider implements AuthenticationProviderInterface
  {
      private $userProvider;
  
      public function __construct(UserProviderInterface $userProvider)
      {
          $this-&gt;userProvider = $userProvider;
      }
  
      public function authenticate(TokenInterface $token)
      {
          $username = $token-&gt;getUser();
          $password = $token-&gt;password;
  
          // here I need to load info using web service ...
  
          if ($username == 'admin' &amp;&amp; $password == 'testadmin') {
              $token-&gt;userObjectType = "User-Staff-MSC";
          } elseif ($username == 'user' &amp;&amp; $password == 'testuser') {
              $token-&gt;userObjectType = "User-Participant-MSC";
          }
  
          $userObjectTypes = explode("-", $token-&gt;userObjectType);
          $allowedEntites = array('Staff', 'Participant');
  
          $roles = array(
              'Participant' =&gt; 'ROLE_USER',
              'Staff' =&gt; 'ROLE_ADMIN'
          );
  
          if (count($userObjectTypes) &gt;= 2 &amp;&amp; in_array($userObjectTypes[1], $allowedEntites)) {
              $tmp = $this-&gt;userProvider-&gt;loadUserByUsername($token-&gt;getUsername());
              $role = $roles[$userObjectTypes[1]];
              $authToken = new ADWSUserToken(array($role));
              $authToken-&gt;setUser($username);
              $authToken-&gt;userObjectType = $token-&gt;userObjectType;
              $authToken-&gt;setAuthenticated(true);
  
              return $authToken;
          }
  
          //$user = $this-&gt;userProvider-&gt;loadUserByUsername($token-&gt;getUsername());
  
          throw new AuthenticationException('The ADWS authentication failed.');
      }
  
      public function supports(TokenInterface $token)
      {
          return $token instanceof ADWSUserToken;
      }
  }
  </code></pre>
  
  <p><strong>ADWSFactory.php</strong></p>
  
  <pre><code>namespace StudentIntranet\GenericBundle\DependencyInjection\Security\Factory;
  
  use Symfony\Component\DependencyInjection\ContainerBuilder;
  use Symfony\Component\DependencyInjection\Reference;
  use Symfony\Component\DependencyInjection\DefinitionDecorator;
  use Symfony\Component\Config\Definition\Builder\NodeDefinition;
  use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface;
  
  class ADWSFactory implements SecurityFactoryInterface
  {
      public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint)
      {
          $providerId = 'security.authentication.provider.adws.'.$id;
          $container
              -&gt;setDefinition($providerId, new DefinitionDecorator('adws.security.authentication.provider'))
              -&gt;replaceArgument(0, new Reference($userProvider))
          ;
  
          $listenerId = 'security.authentication.listener.adws.'.$id;
          $listener = $container
              -&gt;setDefinition($listenerId, new DefinitionDecorator('adws.security.authentication.listener'))
          ;
  
          return array($providerId, $listenerId, $defaultEntryPoint);
      }
  
      public function getPosition()
      {
          return 'pre_auth';
      }
  
      public function getKey()
      {
          return 'adws';
      }
  
      public function addConfiguration(NodeDefinition $node)
      {
      }
  }
  </code></pre>
  
  <p><strong>ADWSUser.php</strong></p>
  
  <pre><code>namespace StudentIntranet\GenericBundle\Security\User;
  use Symfony\Component\Security\Core\User\UserInterface;
  use Symfony\Component\Security\Core\User\EquatableInterface;
  class ADWSUser implements UserInterface, EquatableInterface
  {
      private $username;
      private $password;
      private $salt;
      private $roles;
      public function __construct($username, $password, $salt, array $roles)
      {
          $this-&gt;username = $username;
          $this-&gt;password = $password;
          $this-&gt;salt = $salt;
          $this-&gt;roles = $roles;
      }
      public function getRoles()
      {
          return $this-&gt;roles;
      }
      public function getPassword()
      {
          return $this-&gt;password;
      }
      public function getSalt()
      {
          return $this-&gt;salt;
      }
      public function getUsername()
      {
          return $this-&gt;username;
      }
      public function eraseCredentials()
      {
      }
      public function isEqualTo(UserInterface $user)
      {
          if (!$user instanceof ADWSUser) {
              return false;
          }
          if ($this-&gt;password !== $user-&gt;getPassword()) {
              return false;
          }
          if ($this-&gt;getSalt() !== $user-&gt;getSalt()) {
              return false;
          }
          if ($this-&gt;username !== $user-&gt;getUsername()) {
              return false;
          }
          return true;
      }
  }
  </code></pre>
  
  <p><strong>ADWSUserProvider.php</strong></p>
  
  <pre><code>namespace StudentIntranet\GenericBundle\Security\User;
  
  use Symfony\Component\Security\Core\User\UserProviderInterface;
  use Symfony\Component\Security\Core\User\UserInterface;
  use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
  use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
  
  class ADWSUserProvider implements UserProviderInterface
  {
      public function loadUserByUsername($username)
      {
          return new ADWSUser($username, '', '', array('ROLE_USER'));
      }
  
      public function refreshUser(UserInterface $user)
      {
          return $user;
      }
  
      public function supportsClass($class)
      {
          return $class === 'StudentIntranet\GenericBundle\Security\User\ADWSUser';
      }
  }
  </code></pre>
  
  <p><strong>StudentIntranetGenericBundle.php</strong></p>
  
  <pre><code>namespace StudentIntranet\GenericBundle;
  
  use StudentIntranet\GenericBundle\DependencyInjection\Security\Factory\ADWSFactory;
  use Symfony\Component\HttpKernel\Bundle\Bundle;
  use Symfony\Component\DependencyInjection\ContainerBuilder;
  
  class StudentIntranetGenericBundle extends Bundle
  {
      public function build(ContainerBuilder $container)
      {
          parent::build($container);
  
          $extension = $container-&gt;getExtension('security');
          $extension-&gt;addSecurityListenerFactory(new ADWSFactory());
      }
  }
  </code></pre>
  
  <p><strong>config.yml</strong></p>
  
  <pre><code>imports:
      - { resource: parameters.yml }
      - { resource: security.yml }
      - { resource: "@StudentIntranetGenericBundle/Resources/config/services.yml" }
  
  framework:
      #esi:             ~
      #translator:      { fallback: %locale% }
      secret:          %secret%
      router:
          resource: "%kernel.root_dir%/config/routing.yml"
          strict_requirements: %kernel.debug%
      form:            ~
      csrf_protection: ~
      validation:      { enable_annotations: true }
      templating:
          engines: ['twig']
          #assets_version: SomeVersionScheme
      default_locale:  "%locale%"
      trusted_proxies: ~
      session:         ~
      fragments:       ~
  
  # Twig Configuration
  twig:
      debug:            %kernel.debug%
      strict_variables: %kernel.debug%
  
  # Assetic Configuration
  assetic:
      debug:          %kernel.debug%
      use_controller: false
      bundles:        [ ]
      #java: /usr/bin/java
      filters:
          cssrewrite: ~
          #closure:
          #    jar: %kernel.root_dir%/Resources/java/compiler.jar
          #yui_css:
          #    jar: %kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar
  
  # Doctrine Configuration
  doctrine:
      dbal:
          driver:   %database_driver%
          host:     %database_host%
          port:     %database_port%
          dbname:   %database_name%
          user:     %database_user%
          password: %database_password%
          charset:  UTF8
          # if using pdo_sqlite as your database driver, add the path in parameters.yml
          # e.g. database_path: %kernel.root_dir%/data/data.db3
          # path:     %database_path%
  
      orm:
          auto_generate_proxy_classes: %kernel.debug%
          auto_mapping: true
  
  # Swiftmailer Configuration
  swiftmailer:
      transport: %mailer_transport%
      host:      %mailer_host%
      username:  %mailer_user%
      password:  %mailer_password%
      spool:     { type: memory }
  </code></pre>
  
  <p>main <strong>routing.yml</strong></p>
  
  <pre><code>student_intranet_student:
      resource: "@StudentIntranetStudentBundle/Resources/config/routing.yml"
      prefix:   /student/
  
  student_intranet_admin:
      resource: "@StudentIntranetAdminBundle/Resources/config/routing.yml"
      prefix:   /admin/
  
  student_intranet_generic:
      resource: "@StudentIntranetGenericBundle/Resources/config/routing.yml"
      prefix:   /
  
  student_intranet_empty:
      resource: "@StudentIntranetEmptyBundle/Resources/config/routing.yml"
      prefix:   /empty/
  </code></pre>
  
  <p><strong>security.yml</strong></p>
  
  <pre><code>jms_security_extra:
      secure_all_services: false
      expressions: true
  
  security:
      encoders:
          #Symfony\Component\Security\Core\User\User: plaintext
          StudentIntranet\GenericBundle\Security\User\ADWSUser: plaintext
  
      role_hierarchy:
          ROLE_ADMIN:       [ROLE_USER, ROLE_ALLOWED_TO_SWITCH]
          #ROLE_ADMIN:       ROLE_USER
          #ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
  
      providers:
          #chain_provider:
          #    chain:
          #        providers: in_memory #[user_provider, in_memory]
          user_provider:
              id: adws.user.provider
          #in_memory:
          #    memory:
          #        users:
          #            user:  { password: userpass, roles: [ 'ROLE_USER' ] }
          #            admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
          #            superadmin: { password: superadminpass, roles: [ 'ROLE_SUPER_ADMIN' ] }
  
      firewalls:
          dev:
              pattern:  ^/(_(profiler|wdt)|css|images|js)/
              security: false
  
          free_area:
              pattern: ^/default/
              anonymous: ~
  
          login:
              pattern:  ^/login$
              security: false
  
          secured_area:
              pattern:    ^/
              adws: true
              form_login:
                  provider:               user_provider
                  check_path:             login_check
                  login_path:             login
              logout:
                  path:   logout
                  target: /
              switch_user: true
  
      access_control:
          - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } #, requires_channel: https
          - { path: ^/student/, roles: ROLE_USER }
          - { path: ^/admin, roles: ROLE_ADMIN }
          #- { path: ^/empty, roles: ROLE_SUPER_ADMIN }
  </code></pre>
  
  <p>GenericBundle <strong>routing.yml</strong></p>
  
  <pre><code>root:
      path:     /
      defaults:
          _controller: FrameworkBundle:Redirect:urlRedirect
          path: /student/
  
  login:
      pattern:  /login
      defaults: { _controller: StudentIntranetGenericBundle:Security:login }
  
  login_check:
      pattern:   /login_check
      #defaults: { _controller: StudentIntranetGenericBundle:Security:loginCheck }
  
  logout:
      pattern:   /logout
      defaults: { _controller: StudentIntranetGenericBundle:Security:logout }
  
  generic_homepage:
      pattern:  /generic
      defaults: { _controller: StudentIntranetGenericBundle:Default:index }
  </code></pre>
  
  <p>GenericBundle <strong>services.yml</strong></p>
  
  <pre><code>parameters:
  #    student_intranet_generic.example.class: StudentIntranet\GenericBundle\Example
  
  services:
  #    student_intranet_generic.example:
  #        class: %student_intranet_generic.example.class%
  #        arguments: [@service_id, "plain_value", %parameter%]
  
      adws.user.provider:
          class: StudentIntranet\GenericBundle\Security\User\ADWSUserProvider
  
      adws.security.authentication.provider:
          class:  StudentIntranet\GenericBundle\Security\Authentication\Provider\ADWSProvider
          arguments: [""]
  
      adws.security.authentication.listener:
          class:  StudentIntranet\GenericBundle\Security\Firewall\ADWSListener
          arguments: ["@security.context", "@security.authentication.manager"]
  </code></pre>
  
  <p><strong>SecurityController.php</strong></p>
  
  <pre><code>namespace StudentIntranet\GenericBundle\Controller;
  
  use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  use Symfony\Component\Security\Core\SecurityContext;
  use Symfony\Component\Validator\Constraints\NotBlank;
  //use Symfony\Component\HttpFoundation\Request;
  
  class SecurityController extends Controller
  {
      public function loginAction()
      {
          $request = $this-&gt;getRequest();
          $session = $request-&gt;getSession();
          $authError = SecurityContext::AUTHENTICATION_ERROR;
  
          // get the login error if there is one
          if ($request-&gt;attributes-&gt;has($authError)) {
              $error = $request-&gt;attributes-&gt;get($authError);
          } else {
              $error = $session-&gt;get($authError);
              $session-&gt;remove($authError);
          }
  
          $form = $this-&gt;createFormBuilder(array())
              -&gt;add('username', 'text', array(
                  'constraints' =&gt; new NotBlank(),
                  ))
              -&gt;add('password', 'password', array(
                  'constraints' =&gt; new NotBlank(),
                  ))
              //-&gt;add('remember_me', 'checkbox', array(
              //  'value' =&gt; 'On',
              //  'required' =&gt; false,
              //  ))
              -&gt;getForm();
  
          return $this-&gt;render(
              'StudentIntranetGenericBundle:Login:index.html.twig',
              array(
                  // last username entered by the user
                  'last_username' =&gt; $session-&gt;get(SecurityContext::LAST_USERNAME),
                  'error' =&gt; $error,
                  'form' =&gt; $form-&gt;createView()
              )
          );
      }
  
      public function loginCheckAction()
      {
          // The security layer will intercept this request
          /* These are not working...
          if ($this-&gt;get('security.context')-&gt;isGranted('ROLE_SUPER_ADMIN')) {
              // ... load admin content here
              return $this-&gt;redirect($this-&gt;generateUrl('student_intranet_empty', array('name' =&gt; 'Super Admin')));
          } elseif ($this-&gt;get('security.context')-&gt;isGranted('ROLE_ADMIN')) {
              // ... load admin content here
              return $this-&gt;redirect($this-&gt;generateUrl('student_intranet_admin', array('name' =&gt; 'Admin')));
          } else {
              // ... load admin content here
              return $this-&gt;redirect($this-&gt;generateUrl('student_intranet_student', array('name' =&gt; 'Student')));
          }
          */
      }
  
      public function logoutAction()
      {
          // The security layer will intercept this request
      }
  }
  </code></pre>
  
  <p><strong>index.html.twig</strong></p>
  
  <pre><code>{% extends 'StudentIntranetGenericBundle::layout.html.twig' %}
  {% block content %}
      {% if error %}
          &lt;div&gt;{{ error.message }}&lt;/div&gt;
      {% endif %}
      &lt;form action="{{ path('login_check') }}" method="post"&gt;
          {# this has CSRF protection #}
          {{ form_widget(form) }}
  
          &lt;button type="submit"&gt;login&lt;/button&gt;
      &lt;/form&gt;
  {% endblock %}
  </code></pre>