1
votes

I am following this guide http://symfony.com/doc/current/cookbook/security/api_key_authentication.html to do the authentication by API KEY.

After calling the last method Authentication token I am able to login a user in, but it doesn't keep the sessions.

return new PreAuthenticatedToken(
        $user,
        $apiKey,
        $providerKey,
        $user->getRoles()
    );

I also tried to do the authentication using this following:

$user = new User("Test", null, array("ROLE_USER"));
$token = new UsernamePasswordToken($user, null, 'secured_area', $user->getRoles());
$this->get('security.context')->setToken($token);
$this->get('session')->set('_security_secured_area',serialize($token));

Both cases I am only able to log a user in for a single page, not for all project.

Security is like the guide:

firewalls:
    secured_area:
        pattern: ^/testproject
        stateless: true
        simple_preauth:
            authenticator: apikey_authenticator

Thanks

[update]

$user = new ApiKeyUserProvider();
$user = $user->loadUserByUsername("111111");

$apiKeyProvider = $this->get('apikey_authenticator');
$token = $apiKeyProvider->authenticateToken("111111",$user);
$this->get('security.context')->setToken($token);
$this->get('session')->set('_security_secured_area',serialize($token));

loadUserByUsername is like symfony guide.

Thanks

2
for the second method you likely need to use your token PreAuthenticatedToken Rather than UsernamePasswordTokenChase

2 Answers

1
votes

The authentication should happen automatically if you are following this guide correctly. All you need to do is append the parameter apikey to the end of your requests.

IE:

www.mydomain.com/testproject/get-some-random-data?apikey=vdsadbrfadbfda

Symfony will pick up this request in your firewall and run it through the ApiKeyAuthenticator.

If you want to keep that authentication stored in the session so that subsequent requests dont need the apikey then you can change the stateless config to false in your security.yml

So change:

firewalls:
    secured_area:
        pattern: ^/testproject
        stateless: true
        simple_preauth:
            authenticator: apikey_authenticator

To:

firewalls:
    secured_area:
        pattern: ^/testproject
        stateless: false
        simple_preauth:
            authenticator: apikey_authenticator

Have a look at: http://symfony.com/doc/current/cookbook/security/api_key_authentication.html#cookbook-security-api-key-session

Have you implemented the refreshUser method in your UserProvider?

public function refreshUser(UserInterface $user)
{
    // this is used for storing authentication in the session
    // but in this example, the token is sent in each request,
    // so authentication can be stateless. Throwing this exception
    // is proper to make things stateless
    throw new UnsupportedUserException();
}

Needs to become:

public function refreshUser(UserInterface $user)
{
    // $user is the User that you set in the token inside authenticateToken()
    // after it has been deserialized from the session

    // you might use $user to query the database for a fresh user
    // $id = $user->getId();
    // use $id to make a query

    // if you are *not* reading from a database and are just creating
    // a User object (like in this example), you can just return it
    return $user;
}
0
votes

I had the same problem and found out that the apiKey is saved as the Token credentials. Those are erased if you don't set the following:

security:
    erase_credentials:    false