Zend_Auth identity versioning
Asked Answered
R

2

2

There is a situation: I store some structured data (e.g. array or object, or even string) as a Zend_Auth identity. From version to version the structure of identity could be changed thus identity from one version could (or could not) be compatible with application code of another version.

I'd like to have an ability to validate whether the stored identity data conform to current version requirements.

As I see from the manual, the verification of whether the identity exists is performed like:

$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
    // Identity exists; get it
    $identity = $auth->getIdentity();
}

But there is no ability to hook into hasIdentity() method or somewhere else to perform the validation.

The only way I see to do that is to implement my own Zend_Auth_Storage_Interface class that will use some other storage as implementation and perform the validation of stored data.

Is there any more proper solution?

Rigi answered 12/3, 2011 at 12:43 Comment(0)
B
2

I'm not totally sure to understand but it looks like you misunderstanding the difference between Authorization and Authentication.

Zend_Auth is about Authentication, therefore you should not use Zend_Auth to process Authorization but Zend_Acl.

However, if what you want is to store an additional information from the Authentication process (ie Database Authentication) you can use the getResultRowObject($returnColumns, $ommitColumns); method.

There are several implementation to get the "Row Object" depending on your current Adapter.

Zend_Auth_Storage_Interface is about storing the result, I don't think you'll need to do such implementation since it's about storing the identity object in session or in a database for example.

What you may want is to use Zend_Acl and construct an Access Control List which defines generically a Role (can be an user), a Resource (your version-ed application), a Privilege (can use or not)


Note: *Most people have difficulties to use Zend_Acl because they think in Module/Controller/Action, but it is just one way to define resource.
A resource can be whatever you want, a entire application, a controller action, a view, another user, a database connection, etc.*

Biggers answered 12/3, 2011 at 13:14 Comment(3)
You're exactly right. I use Zend_Auth to authenticate the user and Zend_Acl to authorize him or her (filtering navigation and verification of permissions on preDispatch). But how could I determine that identity is wrong by means of Zend_Acl? Should it mean that user has no any permissions or something like that?Rigi
To be more concrete: the site consist of member-area only. It means that when user is not logged in, login form must be displayed instead of any page. Otherwise when user is logged in, he is supposed to see that part of site that he is allowed to. So probably in case of wrong identity I have to determine the role of user as "anonymous" and than process it as anonymous.Rigi
You're right, because of how roles works, you can inherit them from the less permissive role to the most powerful. I usually, use guest as my starting role with the only privilege to access to sign in page and login, and then I escalate privilege.Shaped
P
0

Even though you accepted the answer above I believe you need something else.

$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
    // Identity exists - validate if it's valid

    $identity = $auth->getIdentity();
    if (!HelperClass::validateIdentity($identity)) { //you validation method
         /* User has stored identity from previous version. 
          * It may miss some important info (like a role value
          * you added recently). Clear it and require re-login. */
         $auth->clearIdentity();
         $this->_helper->flashMessenger('Please login ...');
         $this->_helper->redirector('login');
    }
    // identity is valid
    $acl = Acl::factory(); //get acl object somehow
    if (!$acl->isAllowed($module.$controller.$action, $identity->role)) {
         throw new AccessDeniedException();
    }
    // else nothing -> user has valid session data and is allowed to access the resource. 
}
Phineas answered 12/3, 2011 at 15:42 Comment(2)
That's right, but I'd like that the logic of "whether the current user is logged in" was incapsulated at some certain place. It would allow to re-use that logic in several places without risk to loose somethong. The Acl seems to be exacly that place. And in your example verification of hasIdentity() and it's validation is distributed between two different classes (pieces of code) that make logic less cohesive.Rigi
AcL is not hte place for that IMO. ACL receives the logged in user and decides whether the user can/cannot access certain resource. It should not decide if the user is/is not logged in...Gomar

© 2022 - 2024 — McMap. All rights reserved.