代码之家  ›  专栏  ›  技术社区  ›  A.Seddighi

symfony 4带有约束验证器的简单表单身份验证

  •  1
  • A.Seddighi  · 技术社区  · 6 年前

    我想在我的自定义登录验证(使用simpleform)中使用constraintvalidator来验证这个包的google recaptcha EWZRecaptchaBundle 我不知道

    security.yaml 主防火墙部分:

        providers:
             default:
                 entity:
                     class: App:User
                     property: phone
        main:
             pattern: ^/
             anonymous: ~
             provider: default
             simple_form:
                   authenticator: App\Security\Authenticator\UserAuthenticator
                   check_path: login
                   login_path: login
                   username_parameter: phone
                   password_parameter: password
                   use_referer: true
             logout:
                   path: logout
    

    我需要使用 Validaitor 在里面 App\Security\Authenticator\UserAuthenticator

    这是我的自定义验证器( 应用程序\安全\身份验证程序\用户身份验证程序 ):

    //...
    
    class UserAuthenticator implements SimpleFormAuthenticatorInterface
    {
        private $encoder;
    
        public function __construct(UserPasswordEncoderInterface $encoder)
        {
            $this->encoder = $encoder;
        }
    
        public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
        {
            try {
                $user = $userProvider->loadUserByUsername($token->getUsername());
            }
            catch (UsernameNotFoundException $exception) {
                throw new CustomUserMessageAuthenticationException("invalid");
            }
    
            $isPasswordValid = $this->encoder->isPasswordValid($user, $token->getCredentials());
            if ($isPasswordValid) {
                return new UsernamePasswordToken($user, $user->getPassword(), $providerKey, $user->getRoles());
            }
    
            throw new CustomUserMessageAuthenticationException("invalid");
        }
    
        public function supportsToken(TokenInterface $token, $providerKey)
        {
            return $token instanceof UsernamePasswordToken && $token->getProviderKey() === $providerKey;
        }
    
        public function createToken(Request $request, $username, $password, $providerKey)
        {
            return new UsernamePasswordToken($username, $password, $providerKey);
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   fgamess    6 年前

    How to Create a Custom Authentication System with Guard

    <?php
    
    namespace App\Security\Authenticator;
    
    
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
    use Symfony\Component\Security\Core\Exception\AuthenticationException;
    use Symfony\Component\Security\Core\User\UserInterface;
    use Symfony\Component\Security\Core\User\UserProviderInterface;
    use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
    use Symfony\Component\Validator\Validator\Validator\ValidatorInterface;
    
    class FormLoginAuthenticator extends AbstractFormLoginAuthenticator
    {
        /**
         * @var UserPasswordEncoderInterface
         */
        private $encoder;
    
        /**
         * @var ValidatorInterface
         */
        private $validator;
    
        /**
         * FormLoginAuthenticator constructor.
         * @param UserPasswordEncoderInterface $encoder
         * @param IsTrueValidator $isTrueValidator
         */
        public function __construct(UserPasswordEncoderInterface $encoder, ValidatorInterface $validator)
        {
            $this->encoder = $encoder;
            $this->validator = $validator;
        }
    
        /**
         * Return the URL to the login page.
         *
         * @return string
         */
        protected function getLoginUrl()
        {
            return '/login';
        }
    
        /**
         * Does the authenticator support the given Request?
         *
         * If this returns false, the authenticator will be skipped.
         *
         * @param Request $request
         *
         * @return bool
         */
        public function supports(Request $request)
        {
            return true;
        }
    
        /**
         *
         * @param Request $request
         *
         * @return mixed Any non-null value
         *
         * @throws \UnexpectedValueException If null is returned
         */
        public function getCredentials(Request $request)
        {
            $violations = $this->validator->validate($request->request->get('g-recaptcha-response'), new IsTrue()); 
            if($violations->count() > 0){ 
                throw new AuthenticationException(self::INVALID_RECAPTCHA); 
            }
            return array(
                'username' => $request->request->get('_username'),
                'password' => $request->request->get('_password'),
            );
        }
    
        /**
         * Return a UserInterface object based on the credentials.
         *
         * The *credentials* are the return value from getCredentials()
         *
         * You may throw an AuthenticationException if you wish. If you return
         * null, then a UsernameNotFoundException is thrown for you.
         *
         * @param mixed $credentials
         * @param UserProviderInterface $userProvider
         *
         * @throws AuthenticationException
         *
         * @return UserInterface|null
         */
        public function getUser($credentials, UserProviderInterface $userProvider)
        {
    
            return $userProvider->loadUserByUsername($credentials['username']);
        }
    
        /**
         * Returns true if the credentials are valid.
         *
         * If any value other than true is returned, authentication will
         * fail. You may also throw an AuthenticationException if you wish
         * to cause authentication to fail.
         *
         * The *credentials* are the return value from getCredentials()
         *
         * @param mixed $credentials
         * @param UserInterface $user
         *
         * @return bool
         *
         * @throws AuthenticationException
         */
        public function checkCredentials($credentials, UserInterface $user)
        {
            $plainPassword = $credentials['password'];
    
            if (!empty($plainPassword) && !$this->encoder->isPasswordValid($user, $plainPassword)) {
                throw new BadCredentialsException();
            }
            return true;
        }
    
        /**
         * Called when authentication executed and was successful!
         *
         * If you return null, the current request will continue, and the user
         * will be authenticated. This makes sense, for example, with an API.
         *
         * @param Request $request
         * @param TokenInterface $token
         * @param string $providerKey The provider (i.e. firewall) key
         *
         * @return Response|null
         */
        public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
        {
            return null;
        }
    }
    

    default services.yaml

    providers:
         default:
             entity:
                 class: App:User
                 property: phone
    main:
         pattern: ^/
         anonymous: ~
         provider: default
         guard:
             authenticators:
                 - App\Security\FormLoginAuthenticator
         logout: ~