Login 如何覆盖sfDoctrineGuard验证程序以允许基于凭据登录

Login 如何覆盖sfDoctrineGuard验证程序以允许基于凭据登录,login,symfony1,symfony-1.4,sfguard,Login,Symfony1,Symfony 1.4,Sfguard,正如标题所说,我需要修改sfDoctrineGuard验证器,以允许基于凭据登录。我拥有以下用户和凭据: username credential administrator super admin user1 public_access user2 user3 public_access 我还有两个应用程序:admin和site。因此,根据这些数据,我需要实现以下目标: user1和

正如标题所说,我需要修改sfDoctrineGuard验证器,以允许基于凭据登录。我拥有以下用户和凭据:

username           credential
administrator      super admin
user1              public_access
user2              
user3              public_access
我还有两个应用程序:admin和site。因此,根据这些数据,我需要实现以下目标:

  • user1和user3可以在站点应用程序中登录,但不能在管理员中登录
  • user2无法登录站点,也无法登录admin
  • 管理员可以在管理员中登录,但不能在站点中登录

有什么帮助吗?

您在这里混合了两件事——用户的身份验证和授权

身份验证意味着您的用户可以登录该网站,并且您已确认此人是正确的人

授权筛选哪些内容可供哪些用户使用(是否经过验证)

因此,您在这里寻找的是阻止那些不应该能够看到
admin
应用程序的用户访问,而不是阻止登录

如果您阻止登录部分(使用验证器、您自己的签名操作或其他方式),您将只阻止想要查看您的
admin
应用程序的匿名用户。当他们尝试登录时,他们将被拒绝,因为他们不是管理员。但是,如果用户登录到
站点
应用程序,然后转到
管理
,则无需额外登录,用户将被授予访问权限(除非您设置了适当的授权)

因此,您需要将
security.yml
文件添加到您的
apps/admin/config
文件夹中,其中包含以下内容:

all:
  is_secure: true
  credentials: super_admin

如果“普通”用户登录并尝试导航到
admin
应用程序,他将被拒绝访问。

首先,您应该将
sfGuardValidatorUser
类从
plugins/sfDoctrineGuardPlugin/lib/validator
复制到
lib/validator
并清除缓存

然后修改它的
doClean
方法来检查用户是否具有所需的权限

class sfGuardValidatorUser extends sfValidatorBase
{
  // ...

  protected function doClean($values)
  {
    $username = isset($values[$this->getOption('username_field')]) ? $values[$this->getOption('username_field')] : '';
    $password = isset($values[$this->getOption('password_field')]) ? $values[$this->getOption('password_field')] : '';

    $callable = sfConfig::get('app_sf_guard_plugin_retrieve_by_username_callable');

    if ($username && $callable)
    {
      $user = call_user_func_array($callable, array($username));
    }
    elseif ($username)
    {
      $user = $this->getTable()->retrieveByUsername($username);
    }
    else
    {
      $user = false;
    }

    /** @var $user sfGuardUser */
    if ($user && $user->isAllowedToLogIn(sfConfig::get('sf_app'), $password))
    {
      return array_merge($values, array('user' => $user));
    }

    if ($this->getOption('throw_global_error'))
    {
      throw new sfValidatorError($this, 'invalid');
    }

    throw new sfValidatorErrorSchema($this, array($this->getOption('username_field') => new sfValidatorError($this, 'invalid')));
  }

  // ...
}
然后将
isAllowedToLogIn
方法添加到
sfGuardUser
类:

public function isAllowedToLogIn($app, $password)
{
  if ('admin' == $app)
  {
    $hasPermission = $this->getIsSuperAdmin() || $this->hasPermission('admin');
  }
  elseif ('site' == $app)
  {
    $hasPermission = $this->hasPermission('public_access');
  }
  else
  {
    $hasPermission = true;
  }

  return $this->getIsActive() && $this->checkPassword($password) && $hasPermission;
}
如果需要,请修改权限检查部分


我建议还添加一个管理组和权限,如果您不能使用
is\u super\u admin
标志,则建议添加函数isAllowedToLogIn()?我是说在哪个文件(路径)?@ReynierPM
lib/model/doctor/sfDoctrineGuardPlugin/sfGuardUser.class.php
我可以作为管理员而不是其他用户进入管理应用程序,但不能使用user1凭据进入站点。我检查了权限,一切似乎都很好。我检查了日志,发现了这个:检测到CSRF攻击。为什么?不管它工作得多么完美,也许我错过了什么,我清除了缓存,重新检查了sfGuard插件的所有权限,现在它工作了,非常感谢,你已经得到了要点和最好的答案。还要感谢迈克尔·特洛伊·奥斯基,你说得对,但用户仍然可以登录,我不希望这样。我的意思是user1没有访问权限,因为他的凭据,但仍然可以登录,我甚至不想这样,我是对的?我不认为这样做有什么意义。如果确实想限制用户登录,可以使用@1ed答案中的代码。请记住,如果没有如上所示的
admin
应用程序的安全保护,限制登录将毫无用处。