ambiguos identity in Zend_Auth_Adapter_DbTable

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

ambiguos identity in Zend_Auth_Adapter_DbTable

Renan de Lima
Hi people,

i had some problems using Zend_Auth_Adapter_DbTable (v1.8.4)

Zend auth adapter works fine for table that contains just users from a single system, but if you make a shared table for authentication, this can generate a problem

for example, table user:
-----------------------------------
| username | password | system_id |
-----------------------------------
|  renanbr | md5(123) |        10 |
|  renanbr | md5(123) |        20 |
-----------------------------------

if you do this:

$adapter = Zend_Auth_Adapter_DbTable();
$adapter->setTableName('user')
        ->setIdentityColumn('username')
        ->setCredentialColumn('password')
        ->setCredentialTreatment('md5(?) and system_id = 20')
        ->setIdentity('renanbr')
        ->setCredential('123');
$result = Zend_Auth::getInstance()->authenticate($adapter)->isValid();

$result is false, the error code is Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS, but just one row has "zend_auth_credential_match = 1"

i think Zend_Auth_Adapter_DbTable::_authenticateValidateResultSet() should check this column (zend_auth_credential_match) and throw error just when "zend_auth_credential_match" is "1" more than one row

OR

Zend_Auth_Adapter_DbTable::_authenticateCreateSelect() should separate password treatment from select where, this way the select won't generate more than 1 row


i've fixed that in my application overwriting Zend_Auth_Adapter_DbTable::getDbSelect(), i put my filters there, but i would like to do this using just Zend_Auth_Adapter_DbTable


what do you think about? is there a better solution for that?

--
Renan de Lima Barbosa
gtalk/msn: [hidden email]
skype: renandelima
+55 61 8166-7755
renandelima.com

Reply | Threaded
Open this post in threaded view
|

Re: ambiguos identity in Zend_Auth_Adapter_DbTable

Ralph Schindler-2

>
> $adapter = Zend_Auth_Adapter_DbTable();
> $adapter->setTableName('user')
>         ->setIdentityColumn('username')
>         ->setCredentialColumn('password')
>         ->setCredentialTreatment('md5(?) and system_id = 20')
>         ->setIdentity('renanbr')
>         ->setCredential('123');
> $result = Zend_Auth::getInstance()->authenticate($adapter)->isValid();
>
> $result is false, the error code is
> Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS, but just one row has
> "zend_auth_credential_match = 1"
>

This is an interesting use case.  I would say that your 'identity', in
this case, is actually the combination of both the username and the
system_id.  The way you are describing it above is that the combination
of the password and system_id makes up the credential (which is
conceptually not what you want.)

One thing you could do is get the select object to further identify the
proper identity.  So, assuming your code above, it might look like this:


$adapter = Zend_Auth_Adapter_DbTable();
$adapter->setTableName('user')
         ->setIdentityColumn('username')
         ->setCredentialColumn('password')
         ->setCredentialTreatment('md5(?)')
         ->setIdentity('renanbr')
         ->setCredential('123')

// add a where clause to the internal select object
$adapter->getDbSelect()->where('system_id = 20');

$result = Zend_Auth::getInstance()->authenticate($adapter)->isValid();

I am pretty sure that will remove the ambiguity from the identity clause
at authenticate() time.

Hope this helps,
Ralph Schindler
Reply | Threaded
Open this post in threaded view
|

Re: ambiguos identity in Zend_Auth_Adapter_DbTable

Renan de Lima
Ralph,

> $adapter->getDbSelect()->where('system_id = 20');
perfect! it works fine!

"getDbSelect()  - Return the preauthentication Db Select object for
userland select query modification"
from method comment

i didn't see that the adapter keep a object in cache (one per adapter
instance), so...
thanks a lot!

2009/7/28 Ralph Schindler <[hidden email]>:

>
>>
>> $adapter = Zend_Auth_Adapter_DbTable();
>> $adapter->setTableName('user')
>>        ->setIdentityColumn('username')
>>        ->setCredentialColumn('password')
>>        ->setCredentialTreatment('md5(?) and system_id = 20')
>>        ->setIdentity('renanbr')
>>        ->setCredential('123');
>> $result = Zend_Auth::getInstance()->authenticate($adapter)->isValid();
>>
>> $result is false, the error code is
>> Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS, but just one row has
>> "zend_auth_credential_match = 1"
>>
>
> This is an interesting use case.  I would say that your 'identity', in this
> case, is actually the combination of both the username and the system_id.
>  The way you are describing it above is that the combination of the password
> and system_id makes up the credential (which is conceptually not what you
> want.)
>
> One thing you could do is get the select object to further identify the
> proper identity.  So, assuming your code above, it might look like this:
>
>
> $adapter = Zend_Auth_Adapter_DbTable();
> $adapter->setTableName('user')
>        ->setIdentityColumn('username')
>        ->setCredentialColumn('password')
>        ->setCredentialTreatment('md5(?)')
>        ->setIdentity('renanbr')
>        ->setCredential('123')
>
> // add a where clause to the internal select object
> $adapter->getDbSelect()->where('system_id = 20');
>
> $result = Zend_Auth::getInstance()->authenticate($adapter)->isValid();
>
> I am pretty sure that will remove the ambiguity from the identity clause at
> authenticate() time.
>
> Hope this helps,
> Ralph Schindler
>



--
Renan de Lima Barbosa
gtalk/msn: [hidden email]
skype: renandelima
+55 61 8166-7755
renandelima.com