簡體   English   中英

記住我不使用Symfony 3.3中的警衛認證

[英]Remember Me not working with guard authentication in symfony 3.3

我正在使用symfony 3.3微型框架。 我沒有使用FOSUserbundle,因為我沒有用戶名和電子郵件(由於社交登錄而不必注冊)。 我正在使用使用symfonys Guard身份驗證系統的自定義身份驗證。 一切正常,但是當我要實現“記住我”功能時。 沒用 以下是我使用過的各種文件。

安全性

# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html
security:

    encoders:
        AdminBundle\Entity\User:
            algorithm: bcrypt

    role_hierarchy:
        ROLE_ADMIN:       ROLE_ADMIN
        ROLE_USER:        ROLE_USER

    providers:
        in_memory:
           memory: ~
        token_user_provider:
            entity:
                class: AdminBundle:User
                property: authToken

        login_form_provider:
            entity:
                class: AdminBundle:User
                property: email

    firewalls:
        main:
            pattern: ^/api/
            provider: token_user_provider
            logout:       true
            anonymous:    true
            guard:
                authenticators:
                    - api_key_authenticator
        admin:
            anonymous: ~
            provider: login_form_provider
            logout:
                path:   admin_logout
                target: admin_login
            guard:
                authenticators:
                    - form_authenticator
            remember_me:
                secret:   '%secret%'
                lifetime: 604800     # 1 week
                path:     ^/admin/

    access_control:
        - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/forgot-password, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/reset-password, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, roles: [IS_AUTHENTICATED_FULLY,IS_AUTHENTICATED_REMEMBERED] }
        - { path: ^/api/user/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/user/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/user/forgot-password, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/page/about-us, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/page/terms-and-condition, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/page/faq, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/page/privacy-policy, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/consent/submit, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/, roles: ROLE_USER }

LoginFormAuthenticator.php

<?php

namespace AdminBundle\Security;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
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\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;

class LoginFormAuthenticator extends AbstractGuardAuthenticator {

    /**
     * @var \Symfony\Component\Routing\RouterInterface
     */
    private $router;

    /**
     * @var \Symfony\Component\DependencyInjection\ContainerInterface
     */
    private $container;

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

    /**
     * Creates a new instance of FormAuthenticator
     */
    public function __construct(RouterInterface $router, ContainerInterface $container) {
        $this->router = $router;
        $this->container = $container;
    }

    /**
     * {@inheritdoc}
     */
    public function getCredentials(Request $request) {

        if ($request->get('_route') != 'admin_login' || !$request->isMethod('POST')) {
            return null;
        }

        // Check invalid CSRF token
        $csrfToken = $request->request->get('_csrf_token');
        $csrftokenManager = $this->container->get('security.csrf.token_manager');
        if (false === $csrftokenManager->isTokenValid(new CsrfToken('authenticate', $csrfToken))) {
            throw new InvalidCsrfTokenException('Invalid CSRF token.');
        }

        return array(
            'email' => $request->request->get('email'),
            'password' => $request->request->get('password'),
        );
    }

    /**
     * {@inheritdoc}
     */
    public function getUser($credentials, UserProviderInterface $userProvider) {
        try {
            return $userProvider->loadUserByUsername($credentials['email']);
        } catch (UsernameNotFoundException $e) {
            throw new CustomUserMessageAuthenticationException($this->failMessage);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function checkCredentials($credentials, UserInterface $user) {

        if(!in_array('ROLE_ADMIN', $user->getRoles()))
        {
            throw new CustomUserMessageAuthenticationException("You don't have right to access this page.");
        }

        $factory = $this->container->get('security.encoder_factory');
        $encoder = $factory->getEncoder($user);
        $salt = $user->getSalt();
        if($encoder->isPasswordValid($user->getPassword(), $credentials['password'], $salt)) {
            return true;
        }

        throw new CustomUserMessageAuthenticationException($this->failMessage);
    }

    /**
     * {@inheritdoc}
     */
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) {
        $url = $this->router->generate('admin_dashboard');
        return new RedirectResponse($url);
    }

    /**
     * {@inheritdoc}
     */
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception) {
        $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
        $url = $this->router->generate('admin_login');
        return new RedirectResponse($url);
    }

    /**
     * {@inheritdoc}
     */
    public function start(Request $request, AuthenticationException $authException = null) {
        $url = $this->router->generate('admin_login');
        return new RedirectResponse($url);
    }

    /**
     * {@inheritdoc}
     */
    public function supportsRememberMe() {
        return true;
    }

}

開發日志

[2017-11-10 14:44:24] request.INFO: Matched route "admin_dashboard". {"route":"admin_dashboard","route_parameters":{"_controller":"AdminBundle\\Controller\\DashboardController::indexAction","_route":"admin_dashboard"},"request_uri":"http://localhost/bitcoin-consentsy/public/index.php/admin/dashboard","method":"GET"} []
[2017-11-10 14:44:24] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"admin","authenticators":1} []
[2017-11-10 14:44:24] security.DEBUG: Calling getCredentials() on guard configurator. {"firewall_key":"admin","authenticator":"AdminBundle\\Security\\LoginFormAuthenticator"} []
[2017-11-10 14:44:24] security.DEBUG: Remember-me cookie detected. [] []
[2017-11-10 14:44:25] doctrine.DEBUG: SELECT t0.id AS id_1, t0.email AS email_2, t0.password AS password_3, t0.is_active AS is_active_4, t0.device_id AS device_id_5, t0.device_type AS device_type_6, t0.provide AS provide_7, t0.identifier AS identifier_8, t0.roles AS roles_9, t0.auth_token AS auth_token_10, t0.reset_token AS reset_token_11, t0.is_registration_mail_sent AS is_registration_mail_sent_12, t0.firstname AS firstname_13, t0.lastname AS lastname_14, t0.created_at AS created_at_15, t0.updated_at AS updated_at_16 FROM users t0 WHERE t0.email = ? LIMIT 1 [""] []
[2017-11-10 14:44:25] security.INFO: User for remember-me cookie not found. [] []
[2017-11-10 14:44:25] security.DEBUG: Clearing remember-me cookie. {"name":"REMEMBERME"} []
[2017-11-10 14:44:25] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
[2017-11-10 14:44:25] security.DEBUG: Access denied, the user is not fully authenticated; redirecting to authentication entry point. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException(code: 403): Access Denied. at E:\\xampp\\htdocs\\bitcoin-consentsy\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\Security\\Http\\Firewall\\AccessListener.php:70)"} []

請幫助我解決問題。 我感謝您的幫助。

好吧,我發現了。

“警告:如果用戶使用“記住我”功能登錄,則僅檢查“ IS_AUTHENTICATED_FULLY”將返回false。”

因此,只需將IS_AUTHENTICATED_FULLY替換為IS_AUTHENTICATED_REMEMBERED

如何檢查用戶是否已在控制器內部登錄Symfony2?

請享用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM