2011-09-08 09:59
浏览 38


I set up a Zend_Acl and Zend_Auth scheme where user is authenticated using Zend_Auth_Adapter_Ldap and stored in session. I use a controller plugin to check if $auth->hasIdentity() and $acl->isAllowed() to display login form if needed.

What I want to do is to add login cookies (my implementation of best practices), and API keys in addition to the session check in Zend_Auth. I also need to switch the role to 'owner', on content created by the user.

My concerns:

  • Login cookie should only be used as fallback if regular session auth fails, and thus the session should be authenticated
  • API keys should be used as fallback if both login cookie and session cookie fails
  • I don't want to store the password anywhere, it should only reside in LDAP
  • I need persistent storage of the identity, as looking it up in LDAP is not possible without full username and password
  • The role is dependent both on LDAP group membership (which needs to be persistently stored), and if the identity should be considered owner of the content (meaning it's changing in between requests, unless admin)

What's a good pattern / approach to solve this using Zend Framework MVC and Zend_Auth + Zend_Acl ?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • duanlan6259
    duanlan6259 2011-09-11 09:30

    you can create your own adapter/storage classes, with implementing Zend_Auth_Adpater_Interface and Zend_Auth_Storage_Interface

    In these classes, you can re-use original adapters (like LDAP) or storages, and only write the code that implements your auth rules.

    for example, using multiple sources for the Zend_Auth_Adapter :

    class My_Auth_Adapter implements Zend_Auth_Adapter_Interface
        private $ldapAdapter;
        private $cookieAdapter;
        private $apiKeyAdapter;
        public function __construct($ldapAdapter, $cookieAdapter, $apiKeyAdapter) {
            $this->ldapAdapter = $ldapAdapter;
            $this->cookieAdapter = $cookieAdapter;
            $this->apyKeyAdapter = $apiKeyAdapter;
        public function authenticate()
             if ($this->ldapAdapter->authenticate()) {
                 //return the Zend_Auth_Restult
             } elseif ($this->cookieAdapter->authenticate() {
                //return the result
             } elseif ($this->apiKeyAdapter->authenticate() {
               //return the result
             } else {
               //Create and return a Zend_Auth_Result which prevents logging in

    I am not sure to understand your login rules, but the concept remains the same for the Storage class :

     class My_Auth_Storage implements Zend_Auth_Storage_Interface
      private $sessionStorage;
      private $cookieStorage;
      private $apiStorage;
      public function read()
          if (!$this->sessionStorage->isEmpty())
               return $this->sessionStorage->read();
          } elseif (!$this->cookieStorage->isEmpty())
               return $this->cookieStorage->read();
          } //And so one, do not forget to implement all the interface's methods

    With this implementation, you can have multiple credential sources, and multiple session storage engines (cookie, session, db, or whatever you want to use).

    For your acl concerns, you can fetch the LDAP group in you controller plugin and store it wherever you need, after authentication. You can then use a second plugin that checks ACLs on each request.

    点赞 评论