Zend 2 + doctrine 2 Auth Adapter
Asked Answered
L

1

6

I'm looking for a tutorial on authentication with Zend 2 and Doctrine 2. In particular the creation of the controller and adapter.

The official documentation is too global not help me enough.

thank you

EDIT:

i use "Doctrine Entity" (namespace User\Entity;)

The Entity is register in module.config.php file :

'doctrine' => array(
    'driver' => array(
        __NAMESPACE__ . '_driver' => array(
            'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
            'cache' => 'array',
            'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity')
        ),
        'orm_default' => array(
            'drivers' => array(
                __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
            )
        )          
    ),
)

But now, how can i point my identityClass key to my adapter ? Controller :

use Zend\Mvc\Controller\AbstractActionController,
    Zend\View\Model\ViewModel,
    Zend\Authentication\AuthenticationService,
    Doctrine\ORM\EntityManager,
    DoctrineModule\Authentication\Adapter\ObjectRepository as DoctrineAdapter,        
    User\Entity\User,  
    User\Form\UserForm;
class UserController extends AbstractActionController 
{
protected $em;

public function setEntityManager(EntityManager $em)
{
    $this->em = $em;
}

public function getEntityManager()
{
    if (null === $this->em)
        $this->em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
    return $this->em;
} 

public function getRepository()
{
    if (null === $this->em) 
        $this->em = $this->getEntityManager()->getRepository('User\Entity\User');
    return $this->em;
} 

public function loginAction()
{
    ....
    ????????????
    $adapter = new DoctrineAdapter();
    $adapter->setIdentityValue($username);
    $adapter->setCredentialValue($password);
    $auth = new AuthenticationService();    
    $result=$auth->authenticate($adapter);
    ????????????

}

}

I've got this error : Call to a member function getRepository() on a non-object in ...doctrine\doctrine-module\src\DoctrineModule\Options\AuthenticationAdapter.php on line 132 line 123 : return $this->objectManager->getRepository($this->identityClass);

Lakesha answered 23/8, 2012 at 12:56 Comment(0)
M
15

There are lots of ways to do it, but DoctrineModule for zf2 ships with a doctrine based authentication adapter (DoctrineModule\Authentication\Adapter\ObjectRepository). There is also a factory to create the adapter (DoctrineModule\Service\AuthenticationAdapterFactory). DoctrineMongoODMModule has it's module.config.php set up to use these services. (Note that the factory and adapter will work with ORM, but I'm not sure if the config keys have been added to DoctrineORMModule yet - perhaps someone who reads this would like create a PR for that?) These are the relevant config keys:

    'authenticationadapter' => array(
        'odm_default' => array(
            'objectManager' => 'doctrine.documentmanager.odm_default',
            'identityClass' => 'Application\Model\User',
            'identityProperty' => 'username',
            'credentialProperty' => 'password',
            'credentialCallable' => 'Application\Model\User::hashPassword'
        ),
    ),

The identityClass is the doctrine document that represents your authenticated user. The identityProperty is the normally the username. getUsername will be called by the adapter to access this. credentialProperty is normally the password. getPassword will be called by the adapter to access this. credentialCallable is optional. It should be a callable (method, static method, closure) that will hash the credentialProperty - you don't need to do this, but it's normally a good idea. The adapter will expect the callable to have the following form: function hashPassword($identity, $plaintext).

To get the authentication adapter use:

$serviceLocator->get('doctrine.authenticationadapter.odm_default');

Note that all this only gives you an authetication adapter, it doesn't actually do the authentication. Authentication is done something like this:

$adapter = $serviceLocator->get('doctrine.authenticationadapter.odm_default');
$adapter->setIdentityValue($username);
$adapter->setCredentialValue($password);
$authService = new Zend\Authentication\AuthenticationService
$result = $authService->authenticate($adapter);

This will store the whole doctrine document of the authenticated user in the session object. If you want to store only the document ID in the session object, and retrieve the rest of the authetnicated user document form the DB each request, then take a look at DoctrineModule\Authentication\Storage\ObjectRepository. This provides a new StorageInterface for the Zend\Authentication\AuthenticationService.

Myeloid answered 23/8, 2012 at 23:42 Comment(7)
hi, thanks a lot for the tips. I'm trying to use DoctrineModule\Authentication\Adapter\ObjectRepository as DoctrineAdapter. but when i call $result=$adapter->authenticate() i've got this error : Call to a member function getRepository() on a non-object. How and where do I define my identityClass ?Lakesha
Your identity class should be a Doctrine Document (for ODM) or Doctrine Entity (for ORM). Define it as you would any document/entity. (Don't forget to register your document/entity with a driver key in your module.config.php as you will have done for all your other documents/entities). Once you have created your identity class, use the identityClass key to point your adapter to it. In the example above, the identity class is Application\Model\User, but you can make it whatever you want.Myeloid
i really appreciate your help. I just edit my post to located my problem.Lakesha
@Lakesha To me it looks like your problems are not with authentication, but with simply making entities work. In particular the namespacing looks inconsistent. So, you say you are using User\Entity, then your driver looks like it is registering MyModule\Entity\User. Then in your controller class, you are trying to get the registry of User\Entity\User. Before attempting to set up authentication, make sure you have your doctrine entities working properly. At least test to make sure $em->persist($entity) and $repository->find($id) are working.Myeloid
Okay, the module and the entity have the same name "User". Knowing that, is it more understandable to you ?Lakesha
okay its work. I had specified @options like this : $adapter->setOptions(array( 'objectManager'=>$this->getEntityManager(), 'identityClass'=>'User\Entity\User', 'identityProperty'=>'username', 'credentialProperty'=>'password' )); :-) thanksLakesha
The Doctrine document has now covered this for ORM: AuthenticationIntranuclear

© 2022 - 2024 — McMap. All rights reserved.