Warning if deploying across multiple load-balanced webservers

Be warned that the default implementation of CSecurityManager generates a validation key based on a random number. This key is used to hash the user identification & state cookie.

This will cause you a problem if you are running multiple installations of your application and expect users to be identified (using autoLogin) across any of the nodes. It won’t work, because the hashed cookie won’t validate on any installation other than the one that generated it!

The problem was missed by us at the crucial testing phase, because we only system test on a single webserver<–>DB tier. Then at deployment time, the same web application gets installed on multiple webservers, behind a load balancer. We found we were getting lots of feedback from frustrated users saying “Your site keeps forgetting who I am”. A lesson learnt :)

Our solution was simply to fix the validation key to a constant value, which is configured in an application startup hook (by subclassing CWebApplication), which calls Yii::app()->setGlobalState(CSecurityManager::STATE_VALIDATION_KEY, some_constant_value); This way, all nodes hash and decrypt with the same fixed entity, so cookies are readable by any regardless of which created it.

You can use a simpler approach by configuring the ‘securityManager’ component in app config:




'components'=>array(

   'securityManager'=>array(

      'validationKey'=>'xyz....',

   ),

)



Excellent, thanks. I thought you could only configure public class member variables this way in config. Your solution works (I assume) because the public setter method for the private variable gets called.

I use like this

‘components’=>array(

	'securityManager'=&gt;array(


  		'validationKey'=&gt;'aaa',


	),...

it does not work, I do the encrypt() in firefox, and all goes well in firefox, but when I change to the other browsers(ie, chrome,safari) ,it still get error

PHP Error

Description

mcrypt_generic_init() [<a href=‘function.mcrypt-generic-init’>function.mcrypt-generic-init</a>]: Iv size incorrect; supplied length: 2, needed: 8

Source File

E:\eclipse\workspace\Yii\framework\base\CSecurityManager.php(183)

00171: * @param string data to be decrypted.

00172: * @return string the decrypted data

00173: * @throws CException if PHP Mcrypt extension is not loaded

00174: */

00175: public function decrypt($data)

00176: {

00177: if(extension_loaded(‘mcrypt’))

00178: {

00179: $module=mcrypt_module_open(MCRYPT_3DES, ‘’, MCRYPT_MODE_CBC, ‘’);

00180: $key=substr(md5($this->getEncryptionKey()),0,mcrypt_enc_get_key_size($module));

00181: $ivSize=mcrypt_enc_get_iv_size($module);

00182: $iv=substr($data,0,$ivSize);

00183: mcrypt_generic_init($module,$key,$iv);

00184: $decrypted=mdecrypt_generic($module,substr($data,$ivSize));

00185: mcrypt_generic_deinit($module);

00186: mcrypt_module_close($module);

00187: return rtrim($decrypted,"\0");

00188: }

00189: else

00190: throw new CException(Yii::t(‘yii’,‘CSecurityManager requires PHP mcrypt extension to be loaded in order to use data encryption feature.’));

00191: }

00192:

00193: /**

00194: * Prefixes data with an HMAC.

00195: * @param string data to be hashed.

Hi qiang ,

please explain it detail . how it works?