2017-02-15 94 views
3

我有一个Symfony 2.8项目,我在其中使用FOSUserBundleFOSUser身份验证方法使用fos_user表来识别和验证凭证以及使用sha512加密的密钥。使用两种验证方法的FOSUserBundle

是否可以修改或扩展某些类,以便万一在表fos_user中找不到用户,请在使用md5加密密钥的用户表中查找它?

更新根据madshvero的日落:

我已经创建了一个用户类:

namespace AppBundle\Security\User; 

use Symfony\Component\Security\Core\User\UserInterface; 
use Symfony\Component\Security\Core\User\EquatableInterface; 

class WebserviceUser implements UserInterface, EquatableInterface 
{ 
    private $username; 
    private $password; 
    private $salt; 
    private $roles; 

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

    public function getRoles() 
    { 
     return $this->roles; 
    } 

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

    public function getSalt() 
    { 
     return $this->salt; 
    } 

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

    public function eraseCredentials() 
    { 
    } 

    public function isEqualTo(UserInterface $user) 
    { 
     if (!$user instanceof WebserviceUser) { 
      return false; 
     } 

     if ($this->password !== $user->getPassword()) { 
      return false; 
     } 

     if ($this->salt !== $user->getSalt()) { 
      return false; 
     } 

     if ($this->username !== $user->getUsername()) { 
      return false; 
     } 

     return true; 
    } 
} 

我还创建的用户提供程序:

namespace AppBundle\Security\User; 

use AppBundle\Security\User\WebserviceUser; 
use Symfony\Component\Security\Core\User\UserProviderInterface; 
use Symfony\Component\Security\Core\User\UserInterface; 
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; 
use Symfony\Component\Security\Core\Exception\UnsupportedUserException; 

class WebserviceUserProvider implements UserProviderInterface 
{ 
    public function loadUserByUsername($username) 
    { 
     // make a call to your webservice here 
     $userData = true; 
     // pretend it returns an array on success, false if there is no user 

     if ($userData) { 
      $username = 'prueba'; 
      $password = 'e10adc3949ba59abbe56e057f20f883e'; // md5('123456') 
      $salt = '';`enter code here` 
      $roles = [ROLE_SUPER_ADMIN]; 
      // ... 

      return new WebserviceUser($username, $password, $salt, $roles); 
     } 

     throw new UsernameNotFoundException(
      sprintf('Username "%s" does not exist.', $username) 
     ); 
    } 

    public function refreshUser(UserInterface $user) 
    { 
     if (!$user instanceof WebserviceUser) { 
      throw new UnsupportedUserException(
       sprintf('Instances of "%s" are not supported.', get_class($user)) 
      ); 
     } 

     return $this->loadUserByUsername($user->getUsername()); 
    } 

    public function supportsClass($class) 
    { 
     return WebserviceUser::class === $class; 
    } 
} 

并修改security.yml:

当然,我还修改了services.yml添加服务app.webservice_user_provider: 服务: app.form.group: 类:的appbundle \表格\ GroupFormType 标签: - {名称:form.type,别名:app_group_registration}

app.form.user: 
     class: AppBundle\Form\ProfileFormType 
     tags: 
      - { name: form.type, alias: app_user_profile } 

    app.webservice_user_provider: 
     class: AppBundle\Security\User\WebserviceUserProvider 

这个正在做,该行为是系统允许fos_user提供商的用户访问,而不是我的C的用户ustom供应商。什么是失败?

这一点,日志:

[2017年2月16日11时37分08秒] request.INFO:匹配的路由 “fos_user_security_check”。 { “route_parameters”:{ “_控制器”: “的appbundle \控制器\ SecurityController :: checkAction”, “_路线”: “fos_user_security_check”}, “REQUEST_URI”: “http://127.0.0.1:8000/app_dev.php/login_check”} []

[2017-02-16 11:37:08] doctrine.DEBUG: SELECT t0.id_aspirante AS id_aspirante1, t0.correo AS correo2, t0.clave AS clave3, t0.status_cuenta AS status_cuenta4 FROM aspirantes2 t0 WHERE t0.correo = ? LIMIT 1 ["userFoo"] [] 

[2017-02-16 11:37:08] doctrine.DEBUG: SELECT t0.id_aspirante AS id_aspirante1, t0.correo AS correo2, t0.clave AS clave3, t0.status_cuenta AS status_cuenta4 FROM aspirantes2 t0 WHERE t0.correo = ? LIMIT 1 ["userFoo"] [] 

[2017-02-16 11:37:08] security.INFO: Authentication request failed. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationServiceException(code: 0): The user provider must return a UserInterface object. at /home/userx/projects/myproj/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php:94, Symfony\\Component\\Security\\Core\\Exception\\AuthenticationServiceException(code: 0): The user provider must return a UserInterface object. at /home/userx/projects/myproj/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php:86)"} [] 

[2017-02-16 11:37:08] security.DEBUG: Authentication failure, redirect triggered. {"failure_path":"/login"} [] 

[2017-02-16 11:37:08] request.INFO: Matched route "fos_user_security_login". {"route_parameters":{"_controller":"AppBundle\\Controller\\SecurityController::loginAction","_route":"fos_user_security_login"},"request_uri":"http://127.0.0.1:8000/app_dev.php/login"} [] 

[2017-02-16 11:37:08] security.INFO: Populated the TokenStorage with an anonymous Token. [] [] 

[2017-02-16 11:37:08] request.INFO: Matched route "_wdt". {"route_parameters":{"_controller":"web_profiler.controller.profiler:toolbarAction","token":"c368df","_route":"_wdt"},"request_uri":"http://127.0.0.1:8000/app_dev.php/_wdt/c368df"} [] 

[2017-02-16 11:37:08] security.INFO: Populated the TokenStorage with an anonymous Token. [] [] 

[2017-02-16 11:37:08] 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 /home/userx/projects/myproj/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AccessListener.php:70)"} [] 

[2017-02-16 11:37:08] security.DEBUG: Calling Authentication entry point. [] [] 

[2017-02-16 11:37:08] request.INFO: Matched route "fos_user_security_login". {"route_parameters":{"_controller":"AppBundle\\Controller\\SecurityController::loginAction","_route":"fos_user_security_login"},"request_uri":"http://127.0.0.1:8000/app_dev.php/login"} [] 

[2017-02-16 11:37:08] security.INFO: Populated the TokenStorage with an anonymous Token. [] [] 

回答

0

阅读我是能够理解的验证方法的逻辑的文件后,我发现它更方便,更容易用于我的项目从数据库的身份验证提供程序。真的是在记录一个非常简单的解决方案:How to Load Security Users from the Database (the Entity Provider)

在我来说,我使用FOSUserBundle是有两个方面的考虑:

  1. 它们必须存在两种身份验证方法:由FOSUserBundle和一个提供的一个由MyBundle提供。
  2. 身份验证过程应尝试在两种方法中验证用户身份。

为此,除了在How to Load Security Users from the Database (the Entity Provider)给出的建议,你必须让他们看起来像这样::

encoders: 
    // The database method of FOSUserBundle 
    FOS\UserBundle\Model\UserInterface: 
     algorithm: sha512 
    // The data base method of mine 
    MyBundle\Entity\MyEntity: 
     //This values depends on how the keys were encrypted in the database 
     algorithm: md5 
     encode_as_base64: false 
     iterations: 0 

providers: 
    chain_provider: 
     chain: 
      providers: [fos_userbundle, aspirante_db] 

    fos_userbundle: 
     id: fos_user.user_provider.username 

    myentity_db: 
     entity: { class: MyBundle\Entity\MyEntity, property: username } 

firewalls: 
    main:                                
     pattern: ^/ 
     fr3d_ldap: ~ 
     form_login: 
      provider: chain_provider //This is the important change 
      check_path: /login_check 
      login_path: /login 
      always_use_default_target_path: true 
      default_target_path:/
     logout: 
      path: /logout 
      target: /login 
     anonymous: true 
    dev: 
     pattern: ^/(_(profiler|wdt)|css|images|js)/ 
     security: false 
    login: 
     pattern: ^/login$ 
     security: false 

这是所有修改security.yml的部分路段。我希望将来有人可以利用这篇文章。非常感谢madshvero的指导。

0

你可以这样做通过创建一个custom provider来检查两个表中的用户,并返回找到的用户。

然后你就可以更新app/config/security.yml使用您的提供商,而不是由FOSUserBundle提供的一种:

security: 
    providers: 
     fos_userbundle: 
      id: the.id.of.your.provider 
+0

嗨madshvero,感谢您的回复如此之快。我真的不想使用我的提供者而不是FOSUser,我希望用户先看看FOSUser提供者,如果他不在我的位置上寻找它。 –

+0

是否允许您的提供者扩展FOSUserBundle提供程序,并首先检查“parent :: loadUserByUsername”是否引发异常,如果是,则使用您自己的逻辑用于其他表?您也可以在您的提供商中使用[FOSUserBundle](https:/提供商)中使用的[用户管理器](https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Model/UserManager.php) /github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Security/UserProvider.php)查看用户 – madshvero