I'm using the SimpleAuthentication feature as described here : http://symfony.com/doc/2.6/cookbook/security/api_key_authentication.html
The purpose is to provide an authentication through a token string passed as a query (get) parameter or a header. This token, let's call it TemporaryAccessToken to avoid confusion with the Sf2 token, is generated by a controller, sent to the user by email (not described here) and should be available for a limited amount of time (there's a valid_until
\DateTime
column in the dedicated entity).
For the record, when the protected page (by the simple_user_account
firewall) is accessed the first time the authentication process goes like this :
MyAuthenticator->createToken()
AuthenticationManager->authenticate()
, which calls MyAuthenticator->authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
Problem is : once the user has been authenticated, and because I'm using stateless: false
in the firewall configuration, the authentication process is not triggered again since there's already a valid Sf2 token in session.
I see 2 logic solutions but I can't figure out how to do this properly :
TemporaryAccessToken.valid_until
column. Is there a way to achieve that "natively" ? (I saw that the remember_me
firewall has a lifetime
parameter)if( $accessToken && $accessToken->isValid() )
line 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 authenticator class looks like :
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
Well, if you need to use session, you can set lifetime
under your 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 lifetime
value to anything in seconds (it defaults to 3600 or 1 hour)
Also, you can try to configure garbage collector.
If this answer was not helpful, please, let me know.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With