/** * Tries to authenticate the given token. Sets isAuthenticated to TRUE if authentication succeeded. * * @param \TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken The token to be authenticated * @return void * @Flow\Session(autoStart=true) */ public function authenticate(\TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken) { if (!$authenticationToken instanceof SingleSignOnToken) { throw new \TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1351008039); } if ($authenticationToken->getAuthenticationStatus() === \TYPO3\Flow\Security\Authentication\TokenInterface::AUTHENTICATION_NEEDED) { // Verify signature with server public key $credentials = $authenticationToken->getCredentials(); $signature = $credentials['signature']; $accessTokenCipher = $credentials['accessToken']; $ssoServer = $this->createSsoServer(); if (!$ssoServer->verifyCallbackSignature($accessTokenCipher, $signature)) { throw new Exception('Could not verify signature of access token', 1351008742); } $ssoClient = $this->ssoClientFactory->create(); $accessToken = $ssoClient->decryptCallbackAccessToken($accessTokenCipher); if ($accessToken === '') { throw new Exception('Could not decrypt access token', 1351690950); } $authenticationData = $ssoServer->redeemAccessToken($ssoClient, $accessToken); // TODO Check validity of authentication data (presence of "account" and "sessionId") $account = $this->globalAccountMapper->getAccount($ssoClient, $authenticationData['account']); $globalSessionId = $authenticationData['sessionId']; $this->session->addTag('Flowpack_SingleSignOn_Client-' . $globalSessionId); $authenticationToken->setGlobalSessionId($globalSessionId); $authenticationToken->setAccount($account); $authenticationToken->setAuthenticationStatus(\TYPO3\Flow\Security\Authentication\TokenInterface::AUTHENTICATION_SUCCESSFUL); } elseif ($authenticationToken->getAuthenticationStatus() !== \TYPO3\Flow\Security\Authentication\TokenInterface::AUTHENTICATION_SUCCESSFUL) { $authenticationToken->setAuthenticationStatus(\TYPO3\Flow\Security\Authentication\TokenInterface::NO_CREDENTIALS_GIVEN); } }
/** * Tries to authenticate the tokens in the security context (in the given order) * with the available authentication providers, if needed. * If the authentication strategy is set to "allTokens", all tokens have to be authenticated. * If the strategy is set to "oneToken", only one token needs to be authenticated, but the * authentication will stop after the first authenticated token. The strategy * "atLeastOne" will try to authenticate at least one and as many tokens as possible. * * @return void * @throws \TYPO3\Flow\Security\Exception * @throws \TYPO3\Flow\Security\Exception\AuthenticationRequiredException */ public function authenticate() { $this->isAuthenticated = false; $anyTokenAuthenticated = false; if ($this->securityContext === null) { throw new Exception('Cannot authenticate because no security context has been set.', 1232978667); } $tokens = $this->securityContext->getAuthenticationTokens(); if (count($tokens) === 0) { throw new NoTokensAuthenticatedException('The security context contained no tokens which could be authenticated.', 1258721059); } /** @var $token TokenInterface */ foreach ($tokens as $token) { /** @var $provider AuthenticationProviderInterface */ foreach ($this->providers as $provider) { if ($provider->canAuthenticate($token) && $token->getAuthenticationStatus() === TokenInterface::AUTHENTICATION_NEEDED) { $provider->authenticate($token); if ($token->isAuthenticated()) { $this->emitAuthenticatedToken($token); } break; } } if ($token->isAuthenticated()) { if (!$token instanceof SessionlessTokenInterface) { if (!$this->session->isStarted()) { $this->session->start(); } $account = $token->getAccount(); if ($account !== null) { $this->securityContext->withoutAuthorizationChecks(function () use($account) { $this->session->addTag('TYPO3-Flow-Security-Account-' . md5($account->getAccountIdentifier())); }); } } if ($this->securityContext->getAuthenticationStrategy() === Context::AUTHENTICATE_ONE_TOKEN) { $this->isAuthenticated = true; $this->securityContext->refreshRoles(); return; } $anyTokenAuthenticated = true; } else { if ($this->securityContext->getAuthenticationStrategy() === Context::AUTHENTICATE_ALL_TOKENS) { throw new AuthenticationRequiredException('Could not authenticate all tokens, but authenticationStrategy was set to "all".', 1222203912); } } } if (!$anyTokenAuthenticated && $this->securityContext->getAuthenticationStrategy() !== Context::AUTHENTICATE_ANY_TOKEN) { throw new NoTokensAuthenticatedException('Could not authenticate any token. Might be missing or wrong credentials or no authentication provider matched.', 1222204027); } $this->isAuthenticated = $anyTokenAuthenticated; $this->securityContext->refreshRoles(); }