You are viewing revision #5 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version.
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',
'httpOnly' => true
);
...
That's it !!! This setup has been tested pretty thouroughly, but please provide comments/suggestions below on improving this article.
CDbHttpSession
can't we use this with CDbHttpSession?
yes
It should make no difference what type of session storage you are using. I have used file based and MySQL storage no problem.
Clear your cookies
I would say, don't forget to clear your cookies while testing this thing.
MyWebUser
Where should we put the MyWebUser class file? you did not explain about it.
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?
how about CSRF
how to deal with CSRF cookies?
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', ...
shreyas
Where to add
array(
'id' => 'yourdomain',
?
also i have added the ldap authentication does this works with it?
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.
cross domain check url with status
$.ajax({
type: 'GET',
dataType: "jsonp",
url: "http://api.jqueryww.com/jquery.ajax",
contentType: 'text/plain',
xhrFields: {
withCredentials: false
},
headers: {
},
success: function(jqXHR,textStatus,errorThrown) {
alert(jqXHR.status);
console.log(jqXHR);
},
error: function(jqXHR,textStatus,errorThrown) {
//console.log(textStatus); //console.log(errorThrown); alert(jqXHR.status); console.log(jqXHR);
}
});
Browser specific issue
I have flowed this topic. This is working fine in chrome but not working in mozilla firefox. I have latest browser of both. I don't know why this is not working.
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.