Best way to handle ephemeral tokens using SimplePreAuthenticator & PreAuthenticatedToken

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 { /** * @var AccessTokenManager */ private $accessTokenManager; /** * SimpleUserAuthenticator constructor. * @param AccessTokenManager $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

+6
source share
1 answer

Well, if you need to use a session, you can set lifetime in the config.yml session settings:

 # config.yml framework: session: # handler_id set to null will use default session handler from php.ini handler_id: ~ lifetime: 3600 

You can change the lifetime value for all seconds (by default it is 3600 or 1 hour)

Alternatively, you can try setting up the garbage collector .

If this answer did not help, please let me know.

+1
source

All Articles