2015-10-29 41 views
1

我已经实现与Zend_Auth & Doctrine登录模块,其做工精细的预期,现在我在模块中已经实施Social login太在这种情况下,我需要绕过Password检查,因为一旦用户被第三方供应商确认(如的Facebook等),密码没有在这种情况下需要。ZF2:Zend_Auth的使用Doctrine如何绕过setCredentialValue检查,即在不需要密码校验

因此,我已通过功能社会的登录尝试的情况下修改,

controller

$authService = $this->getServiceLocator()->get('Zend\Authentication\AuthenticationService'); 
$adapter = $authService->getAdapter(); 
$adapter->setIdentityValue($userProfile->email); 
$adapter->setCredentialValue('NA'); // <----- I have used "NA" to notify its an social login 

而且在module.config.php

'doctrine' => array(
     'authentication' => array(
      'orm_default' => array(
       'object_manager' => 'Doctrine\ORM\EntityManager', 
       'identity_class' => 'Account\Entity\Account', 
       'identity_property' => 'username', 
       'credential_property' => 'password', 
       'credential_callable' => function(Entity\Account $user, $passwordGiven) { 
        if($passwordGiven == 'NA') 
         return true; 
        else 
         return md5($passwordGiven) == $user->getHpassword(); 
       }, 
      ) 
     ), 

其工作正常,但我不知道是它是正确的做法吗?任何建议或更可行的方法来做到这一点。

+0

也许不涉及您的问题。但[使用'md5'进行密码加密并不好](http://security.stackexchange.com/a/52463/57364)。 – Wilt

+0

@Wilt“md5”只是暂时的,会让它更安全! –

+0

您正在使用的适配器类是什么? – Wilt

回答

1

学说authentication类注册here in the module.config.php from DoctrineModule

'doctrine' => array(
    'doctrine_factories' => array(
     'cache'     => 'DoctrineModule\Service\CacheFactory', 
     'eventmanager'   => 'DoctrineModule\Service\EventManagerFactory', 
     'driver'    => 'DoctrineModule\Service\DriverFactory', 
     'authenticationadapter' => 'DoctrineModule\Service\Authentication\AdapterFactory', 
     'authenticationstorage' => 'DoctrineModule\Service\Authentication\StorageFactory', 
     'authenticationservice' => 'DoctrineModule\Service\Authentication\AuthenticationServiceFactory', 
    ) 
) 

你可以很容易地覆盖您的自定义工厂这些配置。

我不知道什么是管理这一切,因为我不知道该怎么跟你的社会服务身份验证的样子的最佳方式。您可以覆盖任何这些工厂并添加自定义逻辑,以便从您的社交身份验证服务中注入您的Identity

但也许它甚至会更好地不使用教条认证,但将两个认证解决方案合并到一个定制认证服务类中。那取决于你。

我可以给通过改写存储工厂类从您设置$identity的学说认证存储社会服务的例子。这会给你一个想法如何处理这些事情。

在您的应用程序module.config.php覆盖与您的自定义工厂类存储工厂的关键(请确保您的模块主义模块加载后使钥匙上配置合并覆盖):

'doctrine' => array(
    'doctrine_factories' => array(
     'authenticationstorage' => 'Application\Service\Authentication\CustomStorageFactory', 
    ) 
) 

现在创建这个在您的应用程序文件夹中定制类您CustomStorageFactory例如可以是这样的:

<?php 

namespace Application\Service\Authentication; 

use DoctrineModule\Authentication\Storage\ObjectRepository; 
use Zend\ServiceManager\ServiceLocatorInterface; 
use DoctrineModule\Service\Authentication\StorageFactory; 

/** 
* Customized factory to inject identity from social authentication 
*/ 
class CustomStorageFactory extends StorageFactory 
{ 
    /** 
    * @param \Zend\ServiceManager\ServiceLocatorInterface $serviceLocator 
    * @return \Zend\Authentication\AuthenticationService 
    */ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     // Construct storage like normally by calling parent class 
     $doctrineStorage = parent::__construct($serviceLocator); 

     // Write the identity into the storage 
     $socialService = $serviceLocator->get('SocialAuthenticationService'); 
     if($socialService->hasIdentity()){ 
      $identity = $socialService->getIdentity(); 
      $doctrineStorage->write($identity); 
     } 

     // return the storage 
     return $doctrineStorage; 
    } 
} 

现在你可以做这样的事情:

$serviceLocator= $this->getServiceLocator(); 
$authService = $serviceLocator->get(`Zend\Authentication\AuthenticationService`); 

// Check if we have identity, if not we authenticate 
if(!$authService->hasIdentity()){ 
    $authService->authenticate(); 
) 
$authService->getIdentity(); 
+0

看起来很棒,会实现并让你知道!谢谢 –

+0

@ n01ze您也可以扩展现有的Doctrine适配器类,并直接在其中注入标识。不知道什么会更好地工作... – Wilt

+0

我如何将“$ identityFromSocial”传递给自定义适配器?在服务经理的电话?哦,我是律迷 –

相关问题