/** * Logout page. * * @return \Symfony\Component\HttpFoundation\RedirectResponse */ public function logout(Request $request) { $event = new AccessControlEvent($request); /** @var Token $sessionAuth */ $sessionAuth = $this->session()->get('authentication'); $userName = $sessionAuth ? $sessionAuth->getToken()->getUsername() : false; if ($userName) { $this->app['logger.system']->info('Logged out: ' . $userName, ['event' => 'authentication']); $event->setUserName($userName); } $this->app['dispatcher']->dispatch(AccessControlEvents::LOGOUT_SUCCESS, $event); // Clear the session $this->accessControl()->revokeSession(); $this->session()->invalidate(-1); // Clear cookie data $response = $this->redirectToRoute('login'); $response->headers->clearCookie($this->app['token.authentication.name'], $this->resources()->getUrl('root'), $this->getOption('general/cookies_domain'), $this->getOption('general/enforce_ssl')); return $response; }
/** * Attempt to login a user via the bolt_authtoken cookie. * * @param string $authCookie * @param AccessControlEvent $event * * @return bool */ protected function loginCheckAuthtoken($authCookie, AccessControlEvent $event) { if (!($userTokenEntity = $this->getRepositoryAuthtoken()->getToken($authCookie, $this->getClientIp(), $this->getClientUserAgent()))) { $this->flashLogger->error(Trans::__('general.phrase.error-login-invalid-parameters')); $this->dispatcher->dispatch(AccessControlEvents::LOGIN_FAILURE, $event->setReason(AccessControlEvents::FAILURE_INVALID)); return false; } $checksalt = $this->getAuthToken($userTokenEntity->getUsername(), $userTokenEntity->getSalt()); if ($checksalt === $userTokenEntity->getToken()) { if (!($userEntity = $this->getUserEntity($userTokenEntity->getUsername()))) { $this->dispatcher->dispatch(AccessControlEvents::LOGIN_FAILURE, $event->setReason(AccessControlEvents::FAILURE_INVALID)); return false; } $cookieLifetime = (int) $this->cookieOptions['lifetime']; $userTokenEntity->setValidity(Carbon::create()->addSeconds($cookieLifetime)); $userTokenEntity->setLastseen(Carbon::now()); $this->getRepositoryAuthtoken()->save($userTokenEntity); $this->flashLogger->success(Trans::__('general.phrase.session-resumed-colon')); $this->dispatcher->dispatch(AccessControlEvents::LOGIN_SUCCESS, $event->setDispatched()); return $this->loginFinish($userEntity); } $this->dispatcher->dispatch(AccessControlEvents::LOGIN_FAILURE, $event->setReason(AccessControlEvents::FAILURE_INVALID)); $this->systemLogger->alert(sprintf('Attempt to login with an invalid token from %s', $this->getClientIp()), ['event' => 'security']); return false; }
/** * Check the session is still valid for the device on which it was created, * and. i.e. the username, IP address, and (if configured) the browser agent * values are all still the same. * * @param Token\Token $sessionAuth * * @return boolean */ protected function checkSessionKeys(Token\Token $sessionAuth) { $userEntity = $sessionAuth->getUser(); $tokenEntity = $sessionAuth->getToken(); // The auth token is based on hostname, IP and browser user agent $key = $this->getAuthToken($userEntity->getUsername(), $tokenEntity->getSalt()); if ($key === $tokenEntity->getToken()) { return true; } // Audit the failure $event = new AccessControlEvent($this->requestStack->getCurrentRequest()); /** @var Token\Token $sessionAuth */ $sessionAuth = $this->session->get('authentication'); $userName = $sessionAuth ? $sessionAuth->getToken()->getUsername() : null; $event->setUserName($userName); $this->dispatcher->dispatch(AccessControlEvents::ACCESS_CHECK_FAILURE, $event->setReason(AccessControlEvents::FAILURE_INVALID)); $this->systemLogger->error("Invalidating session: Recalculated session token '{$key}' doesn't match user provided token '" . $tokenEntity->getToken() . "'", ['event' => 'authentication']); $this->systemLogger->info("Automatically logged out user '" . $userEntity->getUsername() . "': Session data didn't match.", ['event' => 'authentication']); return false; }