4

As described in answer of How to use an authenticated user in a Symfony2 functional test? there is a simple solution with Symfony\Component\Security\Core\User\User.

But I have different User class (some necessary additional fields) and I want to authenticate user with it.

How can I setup providders for it?

1
  • 2
    Take a look at this new cookbook article Commented May 14, 2013 at 10:12

4 Answers 4

10

This is a tricky issue discussed here: https://github.com/symfony/symfony/issues/5228 Though it is 2.1, it still happen to me using 2.2.

Here is how I do the test authentication:

// Create a new client to browse the application
$client = static::createClient();
$client->getCookieJar()->set(new Cookie(session_name(), true));

// dummy call to bypass the hasPreviousSession check
$crawler = $client->request('GET', '/');

$em = $client->getContainer()->get('doctrine')->getEntityManager();
$user = $em->getRepository('MyOwnBundle:User')->findOneByUsername('username');

$token = new UsernamePasswordToken($user, $user->getPassword(), 'main_firewall', $user->getRoles());
self::$kernel->getContainer()->get('security.context')->setToken($token);

$session = $client->getContainer()->get('session');
$session->set('_security_' . 'main_firewall', serialize($token));
$session->save();

$crawler = $client->request('GET', '/login/required/page/');

$this->assertTrue(200 === $client->getResponse()->getStatusCode());

// perform tests in the /login/required/page here..

Oh, and the use statements:

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Client;
use Symfony\Component\BrowserKit\Cookie;
Sign up to request clarification or add additional context in comments.

3 Comments

Actually we use LDAP, not cookies. I found different solution, I'll describe it now in the answer.
@DmitryR I don't know about LDAP, and you didn't state it in the question. Do you need to make a dummy call just like session based use?
awesome. just remind that in Symfony 3.0.6 the security.context should be security.token_storage ;)
1

are u using a form login ? or http security?

when using the form login what i do in my tests is i just simulate a user logging in via the login form ...

    /**
     * test of superuser ingelogd geraakt
     */
    public function testSuperAdminLogin()
    {
        $crawler = $this->client->request('GET', '/login');
        $form = $crawler->selectButton('Sign In')->form();
        $user = $this->em->getRepository('NonoAcademyBundle:User')
            ->findOneByUsername('superadmin');
        $crawler = $this->client
            ->submit($form,
                array('_username' => $user->getUsername(),
                        '_password' => $user->getPassword()));

        $this->assertTrue($this->client->getResponse()->isSuccessful());

        $this
            ->assertRegExp('/\/admin\/notifications/',
                $this->client->getResponse()->getContent());
    }

then just use that client and crawler, as they will act as the logged in user. Hope this helps you

2 Comments

Does it mean you store password in plain text?
in this particular case we did, since this particular client actually wanted to be able to re-send existing password, via the pass-forgotten process, instead of starting a resetting procedure, where he is forced to create a new one (we advised him not go go this route, and explained why), but thats what they wanted ...
1

You might also find these helpful especially if you are using a form login

private function doLogin()
{
    $this->client = static::createClient();
    $username = 'your-username';
    $password = 'your-password';

    $crawler = $this->client->request('GET', '/login');
    $form = $crawler->filter('your-submit-button-classname')->form();

    $crawler = $this->client
        ->submit($form,
            array(
                '_username' => $username,
                '_password' => $password,
            )
       );
}

Comments

0

I found a solution.

First we have to create new user provider: FakeUserProvider as described here.
It should implement UserProviderInterface.

Its loadUserByUsername should create necessary user object.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.