Created
June 30, 2015 10:49
-
-
Save aertmann/85c74cc608f7f41daf77 to your computer and use it in GitHub Desktop.
Token based authentication for Flow 3.x
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 Acme\Demo\Controller; | |
| /* * | |
| * This script belongs to the TYPO3 Flow package "Acme.Demo". * | |
| * * | |
| * */ | |
| use TYPO3\Flow\Annotations as Flow; | |
| use Acme\Demo\Domain\Model\Token; | |
| use TYPO3\Flow\Error\Message; | |
| use TYPO3\Flow\Mvc\Controller\ActionController; | |
| /** | |
| * Class Controller | |
| * | |
| * @package Acme\Demo\Controller | |
| */ | |
| class Controller extends ActionController { | |
| /** | |
| * @Flow\Inject | |
| * @var \Acme\Demo\Service\TokenService | |
| */ | |
| protected $tokenService; | |
| /** | |
| * @var \Acme\Demo\Log\LoggerInterface | |
| * @Flow\Inject | |
| */ | |
| protected $logger; | |
| /** | |
| * @var Token | |
| */ | |
| protected $token; | |
| /** | |
| * @return void | |
| */ | |
| protected function initializeAction() { | |
| parent::initializeAction(); | |
| $this->token = $this->tokenService->getToken(); | |
| } | |
| /** | |
| * @return void | |
| * @throws \Exception | |
| */ | |
| public function tokenAction() { | |
| $forwardAction = 'noAccess'; | |
| if (is_null($this->token)) { | |
| $exception = new \Exception('Token not found'); | |
| $this->addFlashMessage('Invalid token', '', Message::SEVERITY_ERROR); | |
| $this->logger->logException($exception, array($this->token)); | |
| throw new $exception; | |
| } elseif (!is_null($this->token->getAccess())) { | |
| $exception = new \Exception('Token does not grant any access'); | |
| $this->logger->logException($exception); | |
| throw new $exception; | |
| } else { | |
| $forwardAction = $this->token->getAccess(); | |
| } | |
| $this->redirect($forwardAction); | |
| } | |
| /** | |
| * @return void | |
| */ | |
| public function indexAction() { | |
| } | |
| /** | |
| * @return void | |
| */ | |
| public function noAccessAction() { | |
| } | |
| /** | |
| * @return void | |
| */ | |
| public function logoutAction() { | |
| $this->tokenService->clear(); | |
| } | |
| } |
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
| privilegeTargets: | |
| 'TYPO3\Flow\Security\Authorization\Privilege\Method\MethodPrivilege': | |
| 'Acme.Demo:AllActions': | |
| matcher: 'method(Acme\Demo\Controller\Controller->(?!(initialize|loggedOut|noAccess)).+Action())' | |
| 'Acme.Demo:NoToken': | |
| matcher: 'method(Acme\Demo\Controller\Controller->(?!(initialize|loggedOut|noAccess)).+Action()) && evaluate(current.tokenService.token == null)' | |
| 'Acme.Demo:Token': | |
| matcher: 'method(Acme\Demo\Controller\Controller->tokenAction())' | |
| 'Acme.Demo:Logout': | |
| matcher: 'method(Acme\Demo\Controller\Controller->logoutAction())' | |
| roles: | |
| 'TYPO3.Flow:Everybody': | |
| privileges: | |
| - | |
| privilegeTarget: 'Acme.Demo:Token' | |
| permission: GRANT | |
| - | |
| privilegeTarget: 'Acme.Demo:NoToken' | |
| permission: DENY | |
| - | |
| privilegeTarget: 'Acme.Demo:Logout' | |
| permission: GRANT |
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
| TYPO3: | |
| Flow: | |
| aop: | |
| globalObjects: | |
| tokenService: 'Acme\Demo\Service\TokenService' | |
| security: | |
| authentication: | |
| providers: | |
| TokenProvider: | |
| provider: 'Acme\Demo\Security\Authentication\Provider\TokenProvider' | |
| requestPatterns: | |
| controllerObjectName: 'Acme\Demo\Controller\.*' | |
| entryPoint: 'WebRedirect' | |
| entryPointOptions: | |
| routeValues: | |
| '@package': 'Acme.Demo' | |
| '@controller': 'AccessApproval' | |
| '@action': 'noAccess' | |
| '@format': 'html' |
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 Acme\Demo\Security\Authentication\Token; | |
| /* * | |
| * This script belongs to the TYPO3 Flow package "Acme.Demo". * | |
| * * | |
| * */ | |
| use Acme\Demo\Domain\Model\Token; | |
| use TYPO3\Flow\Annotations as Flow; | |
| /** | |
| * An authentication token used for session authentication. | |
| */ | |
| class SessionToken extends \TYPO3\Flow\Security\Authentication\Token\AbstractToken { | |
| /** | |
| * @var array | |
| * @Flow\Transient | |
| */ | |
| protected $credentials = array('token' => ''); | |
| /** | |
| * @var Token | |
| */ | |
| protected $token; | |
| /** | |
| * @param \TYPO3\Flow\Mvc\ActionRequest $actionRequest The current action request | |
| * @return void | |
| */ | |
| public function updateCredentials(\TYPO3\Flow\Mvc\ActionRequest $actionRequest) { | |
| if ($actionRequest->getHttpRequest()->getMethod() !== 'GET') { | |
| return; | |
| } | |
| $arguments = $actionRequest->getArguments(); | |
| if (!empty($arguments['token'])) { | |
| $this->credentials['token'] = $arguments['token']; | |
| $this->setAuthenticationStatus(self::AUTHENTICATION_NEEDED); | |
| } | |
| } | |
| /** | |
| * @return Token | |
| */ | |
| public function getToken() { | |
| return $this->token; | |
| } | |
| /** | |
| * @param Token $token | |
| * @return void | |
| */ | |
| public function setToken(Token $token) { | |
| $this->token = $token; | |
| } | |
| /** | |
| * Returns a string representation of the token for logging purposes. | |
| * | |
| * @return string | |
| */ | |
| public function __toString() { | |
| return 'Session token'; | |
| } | |
| } |
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 Acme\Demo\Security\Authentication\Provider; | |
| /* * | |
| * This script belongs to the TYPO3 Flow package "Acme.Demo". * | |
| * * | |
| * */ | |
| use TYPO3\Flow\Annotations as Flow; | |
| use TYPO3\Flow\Security\Authentication\Provider\AbstractProvider; | |
| use TYPO3\Flow\Security\Authentication\TokenInterface; | |
| use TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException; | |
| use Acme\Demo\Security\Authentication\Token\SessionToken; | |
| class TokenProvider extends AbstractProvider { | |
| /** | |
| * @Flow\Inject | |
| * @var \Acme\Demo\Domain\Repository\TokenRepository | |
| */ | |
| protected $tokenRepository; | |
| /** | |
| * Returns the class names of the tokens this provider can authenticate. | |
| * | |
| * @return array | |
| */ | |
| public function getTokenClassNames() { | |
| return array('Acme\Demo\Security\Authentication\Token\SessionToken'); | |
| } | |
| /** | |
| * @param TokenInterface $authenticationToken The token to be authenticated | |
| * @return void | |
| * @throws UnsupportedAuthenticationTokenException | |
| */ | |
| public function authenticate(TokenInterface $authenticationToken) { | |
| if (!$authenticationToken instanceof SessionToken) { | |
| throw new UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1425564602); | |
| } | |
| /** @var SessionToken $authenticationToken */ | |
| $credentials = $authenticationToken->getCredentials(); | |
| if (is_array($credentials) && isset($credentials['token'])) { | |
| if ($token = $this->tokenRepository->findByIdentifier($credentials['token'])) { | |
| $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL); | |
| $authenticationToken->setToken($token); | |
| } else { | |
| $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS); | |
| // @TODO log this | |
| } | |
| } elseif ($authenticationToken->getAuthenticationStatus() !== TokenInterface::AUTHENTICATION_SUCCESSFUL) { | |
| $authenticationToken->setAuthenticationStatus(TokenInterface::NO_CREDENTIALS_GIVEN); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment