/** * This is the default Policy voter, it votes for the access privilege for the given resource * * @param \TYPO3\FLOW3\Security\Context $securityContext The current securit context * @param string $resource The resource to vote for * @return integer One of: VOTE_GRANT, VOTE_ABSTAIN, VOTE_DENY */ public function voteForResource(\TYPO3\FLOW3\Security\Context $securityContext, $resource) { $accessGrants = 0; $accessDenies = 0; foreach ($securityContext->getRoles() as $role) { try { $privilege = $this->policyService->getPrivilegeForResource($role, $resource); } catch (\TYPO3\FLOW3\Security\Exception\NoEntryInPolicyException $e) { return self::VOTE_ABSTAIN; } if ($privilege === NULL) { continue; } if ($privilege === \TYPO3\FLOW3\Security\Policy\PolicyService::PRIVILEGE_GRANT) { $accessGrants++; } elseif ($privilege === \TYPO3\FLOW3\Security\Policy\PolicyService::PRIVILEGE_DENY) { $accessDenies++; } } if ($accessDenies > 0) { return self::VOTE_DENY; } if ($accessGrants > 0) { return self::VOTE_GRANT; } return self::VOTE_ABSTAIN; }
/** * Adds a CSRF token as argument in the URI builder * * @FLOW3\Before("setting(TYPO3.FLOW3.security.enable) && method(TYPO3\FLOW3\Mvc\Routing\UriBuilder->build())") * @param \TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint The current join point * @return void */ public function addCsrfTokenToUri(\TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint) { $uriBuilder = $joinPoint->getProxy(); $arguments = $joinPoint->getMethodArgument('arguments'); $packageKey = isset($arguments['@package']) ? $arguments['@package'] : ''; $subpackageKey = isset($arguments['@subpackage']) ? $arguments['@subpackage'] : ''; $controllerName = isset($arguments['@controller']) ? $arguments['@controller'] : 'Standard'; $actionName = (isset($arguments['@action']) ? $arguments['@action'] : 'index') . 'Action'; $possibleObjectName = '@package\\@subpackage\\Controller\\@controllerController'; $possibleObjectName = str_replace('@package', str_replace('.', '\\', $packageKey), $possibleObjectName); $possibleObjectName = str_replace('@subpackage', $subpackageKey, $possibleObjectName); $possibleObjectName = str_replace('@controller', $controllerName, $possibleObjectName); $possibleObjectName = str_replace('\\\\', '\\', $possibleObjectName); $lowercaseObjectName = strtolower($possibleObjectName); $className = $this->objectManager->getClassNameByObjectName($this->objectManager->getCaseSensitiveObjectName($lowercaseObjectName)); if ($this->policyService->hasPolicyEntryForMethod($className, $actionName) && !$this->reflectionService->isMethodAnnotatedWith($className, $actionName, 'TYPO3\\FLOW3\\Annotations\\SkipCsrfProtection')) { $internalArguments = $uriBuilder->getArguments(); $internalArguments['__csrfToken'] = $this->securityContext->getCsrfProtectionToken(); $uriBuilder->setArguments($internalArguments); } }
/** * Matches a \TYPO3\FLOW3\Mvc\RequestInterface against the configured CSRF pattern rules and searches for invalid * csrf tokens. * * @param \TYPO3\FLOW3\Mvc\RequestInterface $request The request that should be matched * @return boolean TRUE if the pattern matched, FALSE otherwise * @throws \TYPO3\FLOW3\Security\Exception\AuthenticationRequiredException */ public function matchRequest(\TYPO3\FLOW3\Mvc\RequestInterface $request) { if ($this->authenticationManager->isAuthenticated() === FALSE) { return FALSE; } $controllerClassName = $this->objectManager->getClassNameByObjectName($request->getControllerObjectName()); $actionName = $request->getControllerActionName() . 'Action'; if ($this->policyService->hasPolicyEntryForMethod($controllerClassName, $actionName) && !$this->reflectionService->isMethodTaggedWith($controllerClassName, $actionName, 'skipcsrfprotection')) { $internalArguments = $request->getInternalArguments(); if (!isset($internalArguments['__csrfToken'])) { return TRUE; } $csrfToken = $internalArguments['__csrfToken']; if (!$this->securityContext->hasCsrfProtectionTokens()) { throw new \TYPO3\FLOW3\Security\Exception\AuthenticationRequiredException('No tokens in security context, possible session timeout', 1317309673); } if ($this->securityContext->isCsrfProtectionTokenValid($csrfToken) === FALSE) { return TRUE; } } return FALSE; }
/** * Checks, if the current policy allows the retrieval of the object fetched by getObjectDataByIdentifier() * * @FLOW3\Around("within(TYPO3\FLOW3\Persistence\PersistenceManagerInterface) && method(.*->getObjectByIdentifier()) && setting(TYPO3.FLOW3.security.enable)") * @param \TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint The current joinpoint * @return array The object data of the original object, or NULL if access is not permitted */ public function checkAccessAfterFetchingAnObjectByIdentifier(\TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint) { $result = $joinPoint->getAdviceChain()->proceed($joinPoint); if ($this->securityContext->isInitialized() === FALSE) { return $result; } $authenticatedRoles = $this->securityContext->getRoles(); if ($result instanceof \Doctrine\ORM\Proxy\Proxy) { $entityType = get_parent_class($result); } else { $entityType = get_class($result); } if ($this->policyService->hasPolicyEntryForEntityType($entityType, $authenticatedRoles)) { if ($this->policyService->isGeneralAccessForEntityTypeGranted($entityType, $authenticatedRoles) === FALSE) { return NULL; } $policyConstraintsDefinition = $this->policyService->getResourcesConstraintsForEntityTypeAndRoles($entityType, $authenticatedRoles); if ($this->checkConstraintDefinitionsOnResultObject($policyConstraintsDefinition, $result) === FALSE) { return NULL; } } return $result; }
/** * Returns the roles of all active and authenticated tokens. * If no authenticated roles could be found the "Everybody" role is returned * * @return array Array of TYPO3\FLOW3\Security\Policy\Role objects */ public function getRoles() { if ($this->initialized === FALSE) { $this->initialize(); } $roles = array(new Role('Everybody')); if ($this->authenticationManager->isAuthenticated() === FALSE) { $roles[] = new Role('Anonymous'); } else { foreach ($this->getAuthenticationTokens() as $token) { if ($token->isAuthenticated()) { $tokenRoles = $token->getRoles(); foreach ($tokenRoles as $currentRole) { if (!in_array($currentRole, $roles)) { $roles[] = $currentRole; } foreach ($this->policyService->getAllParentRoles($currentRole) as $currentParentRole) { if (!in_array($currentParentRole, $roles)) { $roles[] = $currentParentRole; } } } } } $roles = array_intersect($roles, $this->policyService->getRoles()); } return $roles; }