Last active
October 30, 2016 18:57
-
-
Save jwage/609e19f29b4e9367dbb04da34fb5e49e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace MyProject\Bundle\MainBundle\Security\Authorization\Voter; | |
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; | |
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; | |
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; | |
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; | |
/** | |
* Implements the IS_AUTHENTICATED_RECENTLY attribute. | |
*/ | |
class AuthenticatedRecentlyVoter implements VoterInterface | |
{ | |
private $resolver; | |
private $timeout; | |
/** | |
* Constructor. | |
* | |
* @param AuthenticationTrustResolverInterface $resolver | |
* @param int $timeout The timeout, in seconds | |
*/ | |
public function __construct(AuthenticationTrustResolverInterface $resolver, $timeout = 900) | |
{ | |
$this->resolver = $resolver; | |
$this->timeout = $timeout; | |
} | |
public function supportsAttribute($attribute) | |
{ | |
return 'IS_AUTHENTICATED_RECENTLY' === $attribute; | |
} | |
public function supportsClass($class) | |
{ | |
return true; | |
} | |
public function vote(TokenInterface $token, $object, array $attributes) | |
{ | |
$result = VoterInterface::ACCESS_ABSTAIN; | |
foreach ($attributes as $attribute) { | |
if (!$this->supportsAttribute($attribute)) { | |
continue; | |
} | |
$result = VoterInterface::ACCESS_DENIED; | |
// If the user is being impersonated then grant access | |
foreach ($token->getRoles() as $role) { | |
if ($role->getRole() == 'ROLE_PREVIOUS_ADMIN') { | |
return VoterInterface::ACCESS_GRANTED; | |
} | |
} | |
if ($this->isRecentlyAuthenticated($token)) { | |
// reset the timer | |
$token->setAttribute('last_login', time()); | |
return VoterInterface::ACCESS_GRANTED; | |
} | |
} | |
return $result; | |
} | |
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) | |
{ | |
$token = $event->getAuthenticationToken(); | |
if ($this->resolver->isFullFledged($token)) { | |
$token->setAttribute('last_login', time()); | |
} | |
} | |
private function isRecentlyAuthenticated(TokenInterface $token) | |
{ | |
if ($this->resolver->isFullFledged($token) && $token->hasAttribute('last_login')) { | |
$lastLogin = $token->getAttribute('last_login'); | |
if (is_integer($lastLogin) && $lastLogin >= time() - $this->timeout) { | |
return true; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment