foo*_*bar 6 php security authentication symfony
我正在使用此处所述的SimpleAuthentication功能:http://symfony.com/doc/2.6/cookbook/security/api_key_authentication.html
目的是通过作为查询(get)参数或标头传递的标记字符串提供身份验证.这个令牌,我们称之为TemporaryAccessToken以避免与Sf2令牌混淆,由控制器生成,通过电子邮件发送给用户(此处未描述),并且应该在有限的时间内可用(valid_until \DateTime专用实体中有一列) ).
对于记录,当simple_user_account第一次验证过程如下所示访问受保护的页面(通过防火墙)时:
MyAuthenticator->createToken() AuthenticationManager->authenticate(),调用 MyAuthenticator->authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)问题是:一旦用户通过身份验证,并且因为我stateless: false在防火墙配置中使用,就不会再次触发身份验证过程,因为会话中已经存在有效的Sf2令牌.
我看到2个逻辑解决方案,但我无法弄清楚如何正确地做到这一点:
TemporaryAccessToken.valid_until列中的日期.有没有办法实现"原生"?(我看到remember_me防火墙有一个lifetime参数)if( $accessToken && $accessToken->isValid() )我的身份验证器中的行)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: /
Run Code Online (Sandbox Code Playgroud)
我的身份验证器类看起来像:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
Symfony2版本:2.5.6
好吧,如果您需要使用会话,您可以lifetime在 config.yml 会话设置下进行设置:
# config.yml
framework:
session:
# handler_id set to null will use default session handler from php.ini
handler_id: ~
lifetime: 3600
Run Code Online (Sandbox Code Playgroud)
您可以将lifetime值更改为任何以秒为单位的值(默认为 3600 或 1 小时)
另外,您可以尝试配置垃圾收集器。
如果这个答案没有帮助,请告诉我。