Проблема сессий Symfony4 - PullRequest
0 голосов
/ 22 мая 2018

У меня сейчас проблема с сеансом Managment в Symfony 4, и я не могу найти свою проблему.Прежде всего, вот конфигурация фреймворка:

framework:
    secret: '%env(APP_SECRET)%'
    default_locale: '%env(DEFAULT_LOCATE)%'
    #csrf_protection: true
    #http_method_override: true

    # Enables session support. Note that the session will ONLY be started if you read or write from it.
    # Remove or comment this section to explicitly disable session support.
    session:
        handler_id: session.handler.native_file
        save_path: /tmp/registration
        #save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'

    #esi: true
    #fragments: true
    php_errors:
        log: true

    cache:
        # Put the unique name of your app here: the prefix seed
        # is used to compute stable namespaces for cache keys.
        #prefix_seed: your_vendor_name/app_name

        # The app cache caches to the filesystem by default.
        # Other options include:

        # Redis
        #app: cache.adapter.redis
        #default_redis_provider: redis://localhost

        # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
        #app: cache.adapter.apcu

Конфигурация безопасности

parameters:
    remember_me_field: '_remember_me'
security:
    access_control:
        -
            path: ^/backend
            roles: ROLE_USER
            #requires_channel: https
        -
            path: ^/admin
            roles: ROLE_USER
            #requires_channel: https
        -
            path: ^/security/login/form
            roles: IS_AUTHENTICATED_ANONYMOUSLY
            #requires_channel: https
        -
            path: ^/security/login/authenticate
            roles: IS_AUTHENTICATED_ANONYMOUSLY
            #requires_channel: https
        -
            path: ^/security/logout
            roles: ROLE_USER
            #requires_channel: https
    # https://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
    encoders:
        Symfony\Component\Security\Core\User\UserInterface:
            algorithm: bcrypt
            cost: 12
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: ~
            logout:
                path: /security/login/logout
                target: /security/login/form
            guard:
                authenticators:
                    - App\Security\LoginAuthenticator

            remember_me:
                secret:   '%kernel.secret%'
                lifetime: 31557600 # 1 year in seconds
                path:     /
                remember_me_parameter: '%remember_me_field%'
        default:
            switch_user:
                provider:   ~
                parameter:  _switch_user
                role:       PERMISSION_ALLOWED_TO_SWITCH
            pattern: ^/
            anonymous: ~
            provider: mjr_one

    providers:
        provider:
            entity:
                class: App\Entity\User\User
                property: email

    role_hierarchy:
        #User Type Roles
        ROLE_GUEST:
        ROLE_USER:

и логин безопасности

    <?php
    declare(strict_types=1);

    namespace App\Security;

    use App\Entity\User\User;
    use Symfony\Bridge\Doctrine\Security\User\EntityUserProvider;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
    use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
    use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Routing\Exception\InvalidParameterException;
    use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
    use Symfony\Component\Routing\Exception\RouteNotFoundException;
    use Symfony\Component\Routing\Router;
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder;
    use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
    use Symfony\Component\Security\Core\Exception\AuthenticationException;
    use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
    use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
    use Symfony\Component\Security\Core\Security;
    use Symfony\Component\Security\Core\User\UserInterface;
    use Symfony\Component\Security\Core\User\UserProviderInterface;
    use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;


    /**
     * Class LoginAuthenticator
     *
     * @package   app\Security
     * @author    Chris Westerfield <chris@app.one>
     * @link      http://www.app.one
     * @license   properitary
     * @copyright Chris 
     */
    class LoginAuthenticator extends AbstractGuardAuthenticator
    {
        //Routing
        protected const LOGIN_FORM                   = '/security/login/login';
        protected const ROUTER_LOGIN                 = 'security_login_login';
        protected const ROUTER_FORM                  = 'security_login_form';
        //Form
        protected const LOGIN_FORM_USERNAME_FIELD    = '_username';
        protected const LOGIN_FORM_USERNAME_PASSWORD = '_password';
        //Backend
        protected const BACKEND_INDEX                = 'backend_index_index';
        protected const ROLE_BACKEND                 = 'ROLE_TENANT';
        //Admin
        protected const ROLE_ADMIN                   = 'ROLE_ADMIN';
        protected const ADMIN_INDEX                  = 'admin_index_index';
        //User
        protected const USER_INDEX                   = 'index_index';


        /**
         * Default message for authentication failure.
         *
         * @var string
         */
        protected $failMessage = 'Invalid credentials';

        /**
         * @var UserPasswordEncoder
         */
        protected $encoder;

        /**
         * @var Router
         */
        protected $router;

        /**
         * @var ContainerInterface
         */
        protected $container;

        /**
         * Authenticator constructor.
         *
         * @param Router              $router
         * @param UserPasswordEncoder $encoder
         * @param ContainerInterface  $container
         */
        public function __construct(Router $router, UserPasswordEncoder $encoder, ContainerInterface $container)
        {
            $this->router = $router;
            $this->encoder = $encoder;
            $this->container = $container;
        }

        /**
         * @param Request $request
         *
         * @return array|mixed|null
         */
        public function getCredentials(Request $request)
        : array {
            if ($request->getPathInfo() !== self::LOGIN_FORM || !$request->isMethod('POST')) {
                return [
                    self::LOGIN_FORM_USERNAME_FIELD => null,
                ];
            }

            $user = [
                self::LOGIN_FORM_USERNAME_FIELD    => $request->request->get(self::LOGIN_FORM_USERNAME_FIELD),
                self::LOGIN_FORM_USERNAME_PASSWORD => $request->request->get(self::LOGIN_FORM_USERNAME_PASSWORD),
            ];

            return $user;
        }

        /**
         * @param mixed                 $credentials
         * @param UserProviderInterface $userProvider
         *
         * @return null|UserInterface
         * @throws CustomUserMessageAuthenticationException
         */
        public function getUser($credentials, UserProviderInterface $userProvider)
        : ?UserInterface {
            if (!$userProvider instanceof EntityUserProvider && !$userProvider instanceof UserProviderInterface) {
                return null;
            }

            try {
                return $userProvider->loadUserByUsername($credentials[self::LOGIN_FORM_USERNAME_FIELD]);
            } catch (UsernameNotFoundException $e) {
                throw new CustomUserMessageAuthenticationException($this->failMessage);
            }
        }

        /**
         * @param mixed              $credentials
         * @param UserInterface|User $user
         *
         * @return bool
         * @throws CustomUserMessageAuthenticationException
         */
        public function checkCredentials($credentials, UserInterface $user)
        : bool {
            /** @var User $encoded */
            $plainPassword = $credentials[self::LOGIN_FORM_USERNAME_PASSWORD];

            return $this->encoder->isPasswordValid($user, $plainPassword);
        }

        /**
         * @param Request        $request
         * @param TokenInterface $token
         * @param string         $providerKey
         *
         * @return null|Response
         * @throws \InvalidArgumentException
         * @throws RouteNotFoundException
         * @throws MissingMandatoryParametersException
         * @throws InvalidParameterException
         * @throws AuthenticationCredentialsNotFoundException
         * @throws InvalidArgumentException
         * @throws ServiceNotFoundException
         * @throws ServiceCircularReferenceException
         */
        public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
        : ?Response {
            /** @var User $user */
            $user = $token->getUser();
            $roles = $user->getRoles();
            $validation = $this->container->get('security.authorization_checker');
            if ($validation->isGranted(self::ROLE_BACKEND)) {
                $url = $this->router->generate(self::BACKEND_INDEX);
            } else {
                if ($validation->isGranted(self::ROLE_ADMIN)) {
                    $url = $this->router->generate(self::ADMIN_INDEX);
                } else {
                    $url = $this->router->generate(self::USER_INDEX);
                }
            }
            return new RedirectResponse($url);
        }

        /**
         * @param Request                 $request
         * @param AuthenticationException $exception
         *
         * @return null|Response
         * @throws \InvalidArgumentException
         */
        public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
        : ?Response {
            $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
            $url = $this->router->generate(self::ROUTER_FORM);

            return new RedirectResponse($url);
        }

        /**
         * @param Request                      $request
         * @param AuthenticationException|null $authException
         *
         * @return Response
         * @throws RouteNotFoundException
         * @throws MissingMandatoryParametersException
         * @throws \InvalidArgumentException
         * @throws InvalidParameterException
         */
        public function start(Request $request, AuthenticationException $authException = null)
        : Response {
            $url = $this->router->generate(self::ROUTER_LOGIN);

            return new RedirectResponse($url);
        }

        /**
         * @return bool
         */
        public function supportsRememberMe()
        : bool
        {
            $request = $this->container->get('request_stack')->getCurrentRequest();;
            $field = $this->container->getParameter('remember_me_field');
            return $request->request->has($field);
        }

        /**
         * @param Request $request
         *
         * @return bool
         */
        public function supports(Request $request)
        : bool {
            if ($request->getMethod() === 'POST' && $request->request->has(self::LOGIN_FORM_USERNAME_FIELD) && $request->request->has(self::LOGIN_FORM_USERNAME_PASSWORD)) {
                return true;
            }
            return false;
        }
    }

Моя проблема в том, что я всегда получаюновый идентификатор сессии.Но я не вижу, где я неправильно настроил Symfony.Даже опция Rememberme не помогает. Я также узнал, что security.token не содержит никаких токенов.Я отладил систему и обнаружил, что при каждом запросе вызывается метод уничтожения.Но я не вижу, что я сделал, что это происходит.Любая помощь в ближайшее время

: -)

Крис


На данный момент я нашел следующее:

Если я проверю содержание '@security.token_storage 'то, что получает служба, я получаю

TokenStorage {#1180 ▼
  -token: null
}

, но если я проверяю это в контроллере:

, я получаю это:

TokenStorage {#1180 ▼
  -token: RememberMeToken {#2357 ▶}
}

Влоги я не вижу ошибок.Единственная часть, которая кажется мне странной:

  • Токен был деаутентифицирован после попытки его обновления.
  • Проверка учетных данных аутентификации защиты.
  • Вызов getCredentials () в конфигураторе защиты.
  • Обнаружен файл cookie Remember-me.

Это кажется странныммне.

Прежде чем я забыл это, я использую Symfony 4.0.10 с php 7.2.5

1 Ответ

0 голосов
/ 23 мая 2018

После просмотра всех сервисов я понял это.Я планировал использовать сервис, который требовал хранения токена в фильтре.В настоящее время мне кажется, что этот сервис получает пустой пустой token_storage, который перезаписывает все будущие экземпляры этого.Я удалил слушателя, и система снова заработала, как и ожидалось.

...