Yii 1.1: Single sign on across multiple subdomains

36 followers

This had me stumped for a while so I figured it would be nice to share here to avoid others the grief.

The Requirement

The Yii application is divided into several subdomains, or each subdomain has its own Yii application.

A user should be able to log in to any subdomain and be logged in to another subdomain and the root domain.

The Solution

Actually rather simple through the use of cookies.

First thing is to set the user, session and cookie parameters properly in the main configuration file (only pertinent sections are shown) :

'components' => array(
    'user' => array(
        // enable cookie-based authentication
        'allowAutoLogin' => true,
    ),
    // session configuration
    'session' => array(
        'savePath' => '/some/writeable/path',
        'cookieMode' => 'allow',
        'cookieParams' => array(
            'path' => '/',
            'domain' => '.yourdomain.com',
            'httpOnly' => true,
        ),
    ),

Explanation:

  • The 'savePath' should be set the same across all Yii applications that share the session.

  • Notice the '.' in front of the cookie domain name, this is what tells the cookie to span multiple subdomains, so 'yourdomain.com', 'a.yourdomain.com' and 'b.yourdoamin.com' will be matched.

  • The cookie's 'path' parameter is set to '/', this means the cookie will be valid for all paths.

Next, and this is the crucial bit with Yii (the above cookie configuration is generic PHP), the Yii application ID must be set in the config file:

array(
    'id' => 'yourdomain',

Explanation:

  • The Yii application ID is used to generate a unique signed key, used as a prefix to access user state information. The ID should be set manually so that it is identical for each Yii application that needs to share cookies and sessions.

Finally, the user cookie parameters must also be set to be identical as in the configuration file :

class MyWebUser extends CWebUser
{
    public $identityCookie = array(
        'path' => '/',
        'domain' => '.yourdomain.com',
    );
...

Or you can grab the settings from the configuration settings. This is especially useful when the settings will change, for example to set different domain names and/or paths for local, pre-production and production environments.

class MyWebUser extends CWebUser
{
    public function init()
    {
        $conf = Yii::app()->session->cookieParams;
        $this->identityCookie = array(
            'path' => $conf['path'],
            'domain' => $conf['domain'],
        );
        parent::init();
    }

That's it !!! This setup has been tested pretty thouroughly, but please provide comments/suggestions below on improving this article.

Total 9 comments

#15322 report it
Demitri at 2013/10/28 05:33pm
Web user class must be the same in both apps

Something that isn't really made obvious in this article: the name of the web user class needs to be identical across all applications that share SSO.

The reason for this lies in how the state key prefix is generated (see method getStateKeyPrefix of CWebUser). It does so by concatenating "Yii.", the class name, another period, and finally, the application's ID, and then taking the MD5 sum of the result.

#13975 report it
shreyas d at 2013/07/10 05:07am
shreyas

Where to add array( 'id' => 'yourdomain',

? also i have added the ldap authentication does this works with it?

#13864 report it
vim at 2013/07/03 02:58am
MyWebUser

To use the MyWebUser class, place in into the components directory and add the following to your config:

'components'=>array(
    'user'=>array(
        'class' => 'MyWebUser',
...
#11931 report it
zekus at 2013/02/13 11:40am
how about CSRF

how to deal with CSRF cookies?

#11064 report it
Temir at 2012/12/13 02:16pm
doesn't authenticate

it is working if I check "remember me next time" and doesn't authenticate if I don't. In other words working with cookies and not with sessions. It does create session file but doesn't save details. More about this issue is http://www.yiiframework.com/forum/index.php/topic/38535-single-sign-on-sso-with-yii-user-rights/

can you help please?

#6400 report it
marashi at 2012/01/07 03:30am
MyWebUser

Where should we put the MyWebUser class file? you did not explain about it.

#5014 report it
WallTearer at 2011/09/06 12:18pm
Clear your cookies

I would say, don't forget to clear your cookies while testing this thing.

#4487 report it
ianaré at 2011/07/13 05:54am
yes

It should make no difference what type of session storage you are using. I have used file based and MySQL storage no problem.

#3077 report it
swafsarl at 2011/03/14 11:45am
CDbHttpSession

can't we use this with CDbHttpSession?

Leave a comment

Please to leave your comment.

Write new article