【问题标题】:Symfony3 Custom User Provider doesn't workSymfony3 自定义用户提供程序不起作用
【发布时间】:2017-02-27 21:13:52
【问题描述】:

我尝试按照 Symfony 文档实现所有内容,但身份验证似乎根本不起作用。看看我到底做了什么:

security.yml

security:
    encoders:
        AppBundle\Entity\StUser:
            algorithm: bcrypt
            cost: 12

    providers:
        our_db_provider:
            entity:
                class: AppBundle:Entity:StUser

    firewalls:
        user_secured_area:
            pattern:   ^/([a-z]{2})/account
            provider: our_db_provider
            form_login:
                login_path: login
                check_path: login_check
                csrf_token_generator: security.csrf.token_manager
        default:
            anonymous: ~
            http_basic: ~

StUser.php 实体

namespace AppBundle\Entity;

class StUser implements UserInterface
{
    private $id;
    private $firstName;
    private $lastName;
    private $password;
    private $username;
    private $isAdmin = '0';
    private $confirmed;
    private $created = 'CURRENT_TIMESTAMP';
    private $status = '1';

    public function getId()
    {
        return $this->id;
    }

    public function setFirstName($firstName)
    {
        $this->firstName = $firstName;

        return $this;
    }

    public function getFirstName()
    {
        return $this->firstName;
    }

    public function setLastName($lastName)
    {
        $this->lastName = $lastName;

        return $this;
    }

    public function getLastName()
    {
        return $this->lastName;
    }

    public function setPassword($password)
    {
        $this->password = $password;

        return $this;
    }

    public function getPassword()
    {
        return $this->password;
    }

    public function setUsername($username)
    {
        $this->username = $username;

        return $this;
    }

    public function getUsername()
    {
        return $this->username;
    }

    public function setIsAdmin($isAdmin)
    {
        $this->isAdmin = $isAdmin;

        return $this;
    }

    public function getIsAdmin()
    {
        return $this->isAdmin;
    }

    public function setConfirmed($confirmed)
    {
        $this->confirmed = $confirmed;

        return $this;
    }

    public function getConfirmed()
    {
        return $this->confirmed;
    }

    public function setCreated($created)
    {
        $this->created = $created;

        return $this;
    }

    public function getCreated()
    {
        return $this->created;
    }

    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    public function getStatus()
    {
        return $this->status;
    }

    /* ==== Additional =================================================== */
    public function __construct($username, $password, $salt, array $roles)
    {
        $this->username = $username;
        $this->password = $password;
        /* $this->salt = $salt; */
        /* $this->roles = $roles; */
    }

    public function getRoles()
    {
        return null;
    }

    public function getSalt()
    {
        return null;
    }

    public function eraseCredentials()
    {

    }
}

UserRepository.php 存储库:

namespace AppBundle\Repository;

use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
use Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository implements UserLoaderInterface
{
    public function loadUserByUsername($username)
    {
        return $this->createQueryBuilder('u')
            ->where('u.username = :username OR u.email = :email')
            ->setParameter('username', $username)
            ->setParameter('email', $username)
            ->getQuery()
            ->getOneOrNullResult();
    }
}

AccountController.php

namespace AccountBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class AccountController extends Controller
{
    /**
     * @Route("{_lang}/login", name="login", requirements={"_lang": "pl"})
     */
    public function loginAction(Request $request, $_lang = '')
    {
        $helper = $this->get('security.authentication_utils');
        $error = $helper->getLastAuthenticationError();

        var_dump( $error );

        return $this->render('account/login.html.twig', array(
            'projects' => "",
            'lang' => "pl",
            'allLangs' => "",
            'mainLang' => "",
            'meta_title' => "test",
            'meta_description' => "",
            'meta_keywords' => "",
            'meta_robots' => "",
            'image_src' => "",
            'social_title' => "",
            'social_description' => "",
            'social_url' => "",
            'aaaa' => $helper,

            /* 'last_username' => $lastUsername,
            'error'         => $error, */
        ));
    }
}

login.html.twig 视图

{% block body %}
    <form action="{{ path('login', {'_lang': lang}) }}" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="_username" value="" />

        <label for="password">Password:</label>
        <input type="password" id="password" name="_password" />
        
        <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">

        <button type="submit">login</button>
    </form>
{% endblock %}

什么也没有发生,$helper 和 $error 是空的/null,我在日志中找不到任何东西。我错过了什么。提前致谢。

【问题讨论】:

    标签: php authorization symfony provider


    【解决方案1】:

    在您的 security.yml 中,您需要添加具有默认值的 anonymous 密钥并修复 provider 密钥:

    security.yml

    security:
        encoders:
            AppBundle\Entity\StUser:
                algorithm: bcrypt
                cost: 12
        providers:
            our_db_provider:
                entity:
                    class: AppBundle:StUser # not necessary to put 'Entity' here if your entities are in the Entity Folder
        firewalls:
            user_secured_area:
                anonymous: ~
                pattern:   ^/([a-z]{2})/account
                provider: our_db_provider
                form_login:
                    login_path: login
                    check_path: login_check
                    csrf_token_generator: security.csrf.token_manager
    

    接下来,在您的 AccountController 文件中,为什么不使用特殊的路由参数 _locale ?请阅读:Special Routing Parameters

    然后你在你的路由前加上这样的语言环境参数:

    AccountController.php

    namespace AccountBundle\Controller;
    
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Symfony\Component\HttpFoundation\Request;
    
    class AccountController extends Controller
    {
        /**
         * @Route("/{_locale}/login", name="login", requirements={"_locale": "pl"})
         */
        public function loginAction(Request $request, $_lang = '')
        {
            $helper = $this->get('security.authentication_utils');
            $error = $helper->getLastAuthenticationError();
    
            var_dump( $error );
    
            return $this->render('account/login.html.twig', array(
                'projects' => "",
                'lang' => "pl",
                'allLangs' => "",
                'mainLang' => "",
                'meta_title' => "test",
                'meta_description' => "",
                'meta_keywords' => "",
                'meta_robots' => "",
                'image_src' => "",
                'social_title' => "",
                'social_description' => "",
                'social_url' => "",
                'aaaa' => $helper,
    
                /* 'last_username' => $lastUsername,
                'error'         => $error, */
            ));
        }
    }
    

    我不知道您使用哪种实体映射策略。注释或 xml ? 看看这个(来自文档):

    不要忘记将存储库类添加到mapping definition of your entity

    【讨论】:

      【解决方案2】:

      我试过了,但没有成功。似乎从未调用过任何自定义代码。

      我已经更新了security.yml(当我设置匿名时:~,然后它允许用户在未经授权的情况下打开例如帐户页面):

      security:
          encoders:
              AppBundle\Entity\StUser:
                  algorithm: bcrypt
                  cost: 12
      
          providers:
              our_db_provider:
                  entity:
                      class: AppBundle:StUser
      
          firewalls:
              user_secured_area:
                  pattern:   ^/([a-z]{2})/account
                  # anonymous: ~
                  provider: our_db_provider
                  form_login:
                      login_path: login
                      check_path: login_check
                      csrf_token_generator: security.csrf.token_manager
              default:
                  anonymous: ~
                  http_basic: ~
      

      我还更新了用户实体:

      StUser.orm.yml 实体:

      AppBundle\Entity\StUser:
          type: entity
          table: st_user
          repositoryClass: AppBundle\Repository\UserRepository
          indexes:
              status_username_password:
                  columns:
                      - status
                      - username
                      - password
              status_is_admin_username_password:
                  columns:
                      - status
                      - is_admin
                      - username
                      - password
          id:
              id:
                  type: integer
                  nullable: false
                  options:
                      unsigned: false
                  id: true
                  generator:
                      strategy: IDENTITY
          fields:
              firstName:
                  type: string
                  nullable: true
                  length: 255
                  options:
                      fixed: false
                  column: first_name
              lastName:
                  type: string
                  nullable: true
                  length: 255
                  options:
                      fixed: false
                  column: last_name
              password:
                  type: string
                  nullable: true
                  length: 255
                  options:
                      fixed: false
              username:
                  type: string
                  nullable: true
                  length: 255
                  options:
                      fixed: false
              isAdmin:
                  type: boolean
                  nullable: false
                  options:
                      default: '0'
                  column: is_admin
              confirmed:
                  type: datetime
                  nullable: true
              created:
                  type: datetime
                  nullable: false
                  options:
                      default: CURRENT_TIMESTAMP
              status:
                  type: boolean
                  nullable: false
                  options:
                      default: '0'
          lifecycleCallbacks: {  }
      

      【讨论】:

      • 关于您的 security.yml 中的 anonymous 键,您应该将其放入,因为您登录并且您的 login_check 路径正在防火墙中。如果您拒绝匿名用户访问,您如何让用户进入登录页面登录?然后,您的工作就是使用不同的策略(例如注释或 ACL)保护 account 路径。
      • 另外,尝试将 login 放入 check_path 而不是 login_check
      • 我认为您不需要在防火墙配置中使用 pattern 键,因为您将登录路径名称设置为 login模式和要求。登录路径与您的防火墙模式不匹配 ^/([a-z]{2})/account 不要使用此模式并使用 acl 或注释保护您的帐户路由
      猜你喜欢
      • 2020-04-27
      • 1970-01-01
      • 2014-10-15
      • 1970-01-01
      • 1970-01-01
      • 2014-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多