* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Security\Http\Firewall; use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\SessionUnavailableException; use Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Http\SecurityEvents; use Symfony\Component\Security\Http\HttpUtils; /** * The AbstractAuthenticationListener is the preferred base class for all * browser-/HTTP-based authentication requests. * * Subclasses likely have to implement the following: * - an TokenInterface to hold authentication related data * - an AuthenticationProvider to perform the actual authentication of the * token, retrieve the UserInterface implementation from a database, and * perform the specific account checks using the UserChecker * * By default, this listener only is active for a specific path, e.g. * /login_check. If you want to change this behavior, you can overwrite the * requiresAuthentication() method. * * @author Fabien Potencier * @author Johannes M. Schmitt */ abstract class AbstractAuthenticationListener implements ListenerInterface { protected $options; protected $logger; protected $authenticationManager; protected $providerKey; protected $httpUtils; private $tokenStorage; private $sessionStrategy; private $dispatcher; private $successHandler; private $failureHandler; private $rememberMeServices; /** * @param TokenStorageInterface $tokenStorage A TokenStorageInterface instance * @param AuthenticationManagerInterface $authenticationManager An AuthenticationManagerInterface instance * @param SessionAuthenticationStrategyInterface $sessionStrategy * @param HttpUtils $httpUtils An HttpUtils instance * @param string $providerKey * @param AuthenticationSuccessHandlerInterface $successHandler * @param AuthenticationFailureHandlerInterface $failureHandler * @param array $options An array of options for the processing of a * successful, or failed authentication attempt * @param LoggerInterface|null $logger A LoggerInterface instance * @param EventDispatcherInterface|null $dispatcher An EventDispatcherInterface instance * * @throws \InvalidArgumentException */ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null) { if (empty($providerKey)) { throw new \InvalidArgumentException('$providerKey must not be empty.'); } $this->tokenStorage = $tokenStorage; $this->authenticationManager = $authenticationManager; $this->sessionStrategy = $sessionStrategy; $this->providerKey = $providerKey; $this->successHandler = $successHandler; $this->failureHandler = $failureHandler; $this->options = array_merge(array( 'check_path' => '/login_check', 'login_path' => '/login', 'always_use_default_target_path' => false, 'default_target_path' => '/', 'target_path_parameter' => '_target_path', 'use_referer' => false, 'failure_path' => null, 'failure_forward' => false, 'require_previous_session' => true, ), $options); $this->logger = $logger; $this->dispatcher = $dispatcher; $this->httpUtils = $httpUtils; } /** * Sets the RememberMeServices implementation to use. */ public function setRememberMeServices(RememberMeServicesInterface $rememberMeServices) { $this->rememberMeServices = $rememberMeServices; } /** * Handles form based authentication. * * @throws \RuntimeException * @throws SessionUnavailableException */ final public function handle(GetResponseEvent $event) { $request = $event->getRequest(); if (!$this->requiresAuthentication($request)) { return; } if (!$request->hasSession()) { throw new \RuntimeException('This authentication method requires a session.'); } try { if ($this->options['require_previous_session'] && !$request->hasPreviousSession()) { throw new SessionUnavailableException('Your session has timed out, or you have disabled cookies.'); } if (null === $returnValue = $this->attemptAuthentication($request)) { return; } if ($returnValue instanceof TokenInterface) { $this->sessionStrategy->onAuthentication($request, $returnValue); $response = $this->onSuccess($request, $returnValue); } elseif ($returnValue instanceof Response) { $response = $returnValue; } else { throw new \RuntimeException('attemptAuthentication() must either return a Response, an implementation of TokenInterface, or null.'); } } catch (AuthenticationException $e) { $response = $this->onFailure($request, $e); } $event->setResponse($response); } /** * Whether this request requires authentication. * * The default implementation only processes requests to a specific path, * but a subclass could change this to only authenticate requests where a * certain parameters is present. * * @return bool */ protected function requiresAuthentication(Request $request) { return $this->httpUtils->checkRequestPath($request, $this->options['check_path']); } /** * Performs authentication. * * @return TokenInterface|Response|null The authenticated token, null if full authentication is not possible, or a Response * * @throws AuthenticationException if the authentication fails */ abstract protected function attemptAuthentication(Request $request); private function onFailure(Request $request, AuthenticationException $failed) { if (null !== $this->logger) { $this->logger->info('Authentication request failed.', array('exception' => $failed)); } $token = $this->tokenStorage->getToken(); if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey()) { $this->tokenStorage->setToken(null); } $response = $this->failureHandler->onAuthenticationFailure($request, $failed); if (!$response instanceof Response) { throw new \RuntimeException('Authentication Failure Handler did not return a Response.'); } return $response; } private function onSuccess(Request $request, TokenInterface $token) { if (null !== $this->logger) { $this->logger->info('User has been authenticated successfully.', array('username' => $token->getUsername())); } $this->tokenStorage->setToken($token); $session = $request->getSession(); $session->remove(Security::AUTHENTICATION_ERROR); $session->remove(Security::LAST_USERNAME); if (null !== $this->dispatcher) { $loginEvent = new InteractiveLoginEvent($request, $token); $this->dispatcher->dispatch(SecurityEvents::INTERACTIVE_LOGIN, $loginEvent); } $response = $this->successHandler->onAuthenticationSuccess($request, $token); if (!$response instanceof Response) { throw new \RuntimeException('Authentication Success Handler did not return a Response.'); } if (null !== $this->rememberMeServices) { $this->rememberMeServices->loginSuccess($request, $response, $token); } return $response; } } __halt_compiler();----SIGNATURE:----I+LvxIU9wGIDC2c15jLu6T6KCcNceibysRhRf0Gvcc6XDsUvVgOpbKz3SrPoVk0/FMF+jtCCWOB9v5KF/62d7S6AhINMTLuIh1go8Iw6QhTrIkrl/RDcaRvc5FiS8azmYQroZsiU0kynXN7GK6VfKOZ+HzwtPvuaKOuFf9Ot1CARfMEn5t4TdlmS6AFkg40a01ZTJRhvHbCWpq3/fvwCsLloATDJyiL2ubBlNYk66pb2rkubZNrlexr/eZ7n/c8bI+s/KCWIwDghVMzV/gbMFQdznchUDGEKWN/edf39IyEGH1LUjNIAVmvFmgU9oEh7VQeN5B+i5APU7tBtpzUkThVSyAOPJln2hPfkVGQW5FKpydNIY4azx92Xh0y1hTVYhPgqia0J3Ou7lrJANYbpgiPLRn4voHCCWu0Yy4LtZP/BKDcgJpGJpuCqVpZIJCHpgmCbcaNpoUdeHDJ4bWchOnO+iJidpSK+ScxfQcYE6q+ROFTKKQeyyFEOWi20lCxSOvsloGxjYlq/nXhHMwMMEVA9Cl6fS7WlyYyz6lbBJX+9MbQWP1NL9DKNqekR90Ip5eaVcs3LCJ+lTOg75bdqxE8Dy5bDIefGyTaZkx9/AHMBcodHpRhYevOvw+ezRtzAd37MDVOHizwjewZYmV64fNzgAMfZ+r8j+GckIRIugCo=----ATTACHMENT:----MTMzMTAzNDkwMzQ3ODM3IDUzMDczNDExMTM5NDQ2NjQgNDA0MTgxMzU2MjY0OTM0MA==