2017-02-15 46 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