I am using the SimpleAuthentication function as described here: http://symfony.com/doc/2.6/cookbook/security/api_key_authentication.html
The goal is to provide authentication through a token string passed as a request parameter (get) or header. This token, calling it TemporaryAccessToken , to avoid confusion with the Sf2 token, is generated by the controller, sent to the user by e-mail (not described here) and must be available for a limited period of time (there is a valid_until \DateTime column in the selected object).
To record when a secure page is accessed (via the simple_user_account firewall) when the authentication process is first launched:
- SimplePreAuthenticationListener starts
- Basically, calls
MyAuthenticator->createToken() - It then calls
AuthenticationManager->authenticate() , which calls MyAuthenticator->authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
The problem is this: after user authentication and due to the fact that I use stateless: false in the firewall configuration, the authentication process does not start again, because the session already has a valid Sf2 token.
I see 2 logical solutions, but I can not figure out how to do this correctly:
- make the session valid until the date set in my
TemporaryAccessToken.valid_until column. Is there a way to achieve this βinitiallyβ? (I saw that the remember_me firewall has a lifetime parameter) - or , you can check the expiration of the TemporaryAccessToken again (see the
if( $accessToken && $accessToken->isValid() ) line if( $accessToken && $accessToken->isValid() ) in my Authenticator)
app/config/security.yml
firewalls: simple_user_account: pattern: ^/account/access stateless: false simple_preauth: authenticator: app.security.simple_user_authenticator logout: path: /logout_simple target: /
My authentication class is as follows:
class SimpleUserAuthenticator implements SimplePreAuthenticatorInterface, AuthenticationFailureHandlerInterface { private $accessTokenManager; public function __construct(AccessTokenManager $accessTokenManager) { $this->accessTokenManager = $accessTokenManager; } public function createToken(Request $request, $providerKey) { $TemporaryAccessToken = $request->query->get('simple_user_token'); if (!$TemporaryAccessToken) { throw new BadCredentialsException('No simple_user token found'); } return new PreAuthenticatedToken( 'anonymous', $TemporaryAccessToken, $providerKey ); } public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey) { if( $token->getUser() instanceof SimpleUser ) { $newToken = new PreAuthenticatedToken( $token->getUser(), $token->getCredentials(), $providerKey, array('ROLE_USER') ); return $newToken; } $accessToken = $this->accessTokenManager->getRepository()->findOneByToken($token->getCredentials()); if( $accessToken && $accessToken->isValid() ) { $user = $userProvider->loadUserByUsername($accessToken->getAccount()->getEmailCanonical()); $newToken = new PreAuthenticatedToken( $user, $token->getCredentials(), $providerKey, array('ROLE_USER') ); return $newToken; } } public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { $response = new RedirectResponse( '/login' ); return $response; } public function supportsToken(TokenInterface $token, $providerKey) { return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey; } }
Symfony2 Version: 2.5.6