Simple Single Sign-On for PHP (Ajax compatible)
Associated websites often share user information, so a visitor only has to register once and can use that username and password for all sites. A good example for this is Google. You can use you google account for GMail, Blogger, iGoogle, google code, etc. This is nice, but it would be even nicer if logging in for GMail would mean I’m also logged in for the other websites. For that you need to implement single sign-on (SSO).
There are many single sign-on applications and protocols. Most of these are fairly complex. Applications often come with full user management solutions. This makes them difficult to integrate. Most solutions also don’t work well with AJAX, because redirection is used to let the visitor log in at the SSO server.
I’ve written a simple single sign-on solution (400 lines of code), which works by linking sessions. This solutions works for normal websites as well as AJAX sites.
Without SSO
Let’s start with a website that doesn’t have SSO.

The client requests the index page. The page requires that the visitor is logged in. The server creates a new session and sends redirect to the login page. After the visitor has logged in, it displays the index page.
How it works
When using SSO, when can distinguish 3 parties:
- Client – This is the browser of the visitor
- Broker – The website which is visited
- Server – The place that holds the user information
The broker will talk to the server in name of the client. For that we want the broker to use the same session as the client. However the client won’t pass the session id which it has at the server, since it’s at another domain. Instead the broker will ask the client to pass a token to the server. The server uses the token, in combination with a secret word, to create a session key which is linked session of the client. The broker also know the token and the secret word and can therefore generate the same session key, which it uses to proxy login/logout commands and request info from the server.
First visit
-> Try it! (jan/jan1)<-

When you visit a broker website, it will check to see if a token cookie already exists. It it doesn’t it, the broker sends a redirect to the server, giving the command to attach sessions and specifying the broker identity, a random token and the originally requested URL. It saves the token in a cookie.
The server will generate a session key based on the broker identity, the secret word of the broker and the token and link this to the session of the client. The session key contains a checksum, so hackers can go out and use random session keys to grab session info. The server redirects the client back to the original URL. After this, the client can talk to the broker, the same way it does when not using SSO.
The client requests the index page at the broker. The page requires that the visitor is logged in. The broker generates the session key, using the token and the secret word, and request the user information at the server. The server responds to the broker that the visitor is not logged. The broker redirects the client to the login page.
The client logs in, sending the username and password to the broker. The broker sends the username and password to the server, again passing the session key. The server returns that login is successful to the broker. The broker redirects the client to the index page. For the index page, the broker will request the user information from the server.
Visiting another affiliate
-> Try it! <-

You visit another broker. It also checks for a token cookie. Since each broker is on their own domain, they have different cookies, so no token cookie will be found. The broker will redirect to the server attach to the user session.
The server attaches a session key generated for this broker, which differs from the one for the first broker. It attaches it to the user session. This is the same session the first broker used. The server will redirect back to the original URL.
The client requests the index page at the broker. The broker will request user information from the server. Since the visitor is already logged in, the server returns this information. The index page is shown to the visitor.
Using AJAX / Javascript
-> Try it! <-
SSO and AJAX / RIA applications often don’t go well together. With this type of application, you do not want to leave the page. The application is static and you get the data and do all actions through AJAX. Redirecting an AJAX call to a different website won’t because of cross-site scripting protection within the browser.
With this solution the client only needs to attach the session by providing the server with a token generated by the broker. That attach request doesn’t return any information. After attaching the client doesn’t talk at all to the server any more. Authentication can be done as normal.

The client check for the token cookie. It it doesn’t exists, he requests the attach URL from the broker. This attach url includes the broker name and the token, but not a original request URL. The client will open the received url in an <img> and wait until the image is loaded.
The server attaches the browser session key to the user session. When it’s done it outputs a PNG image. When this image is received by the client, it knows the server has connected the sessions and the broker can be used for authentication. The broker will work as a proxy, passing commands and requests to the sso server and return results to the client.
To conclude
By connecting sessions, you give the broker the power to act as the client. This method can only be used if you trust all brokers involved. The login information is send through the broker, which he can easily store if the broker has bad intentions.
Demo
Broker ‘Alex’
Broker ‘Binck’
AJAX broker – created by Lukasz ‘Uzza’ Lipinski using Ajax.org PlatForm.
Play around, logging in and out at different brokers. Refresh the other after. Available users:
jan / jan1
peter / peter1
bart / bart1
henk / henk1
I need your help with jquery
Are you proficient in jquery? Many users have requested a jquery AJAX example. Unfortunately my jquery skills are minimal
. Perhaps you can help out? You’ll be credited and linked of course.
Download
Download the code @ github
2009-11-16: Updated the software with bugfixes mentioned in comments + alternative for using symlinks.
If I overlooked security issues with this SSO implementation, please leave a comment below.
This is a simple implementation of SSO. If you want enterprise stuff have a look at Novell Single Sign-On.
18 Apr 2009 Arnold Daniels




Nicely written article. However, I can’t help but feel that you are trying to solve the same problem OpenID is solving, just in a different way …
Why implement this, when OpenID exists?
can be useful for someone willing to use SSO in his enterprise, for example between different intranet/extranet solutions.
now problem
user A and user B use the same pc, user A login but don’t logout, when user B visit this website, then user B use user A cookie.
Daniel: OpenID is shared authentication, but not single sign-on. You need to login at each site. The difference is explained at wikipedia http://en.wikipedia.org/wiki/Single_sign-on#Shared_Authentication_Schemes_which_are_not_Single_Sign-On.
Also with this solution you have all the user information in one place. OpenID is purely authentication only.
Caleng: This problem you would also have when you don’t do single sign-on, but authenticate at the website as normal. Therefore this is not within the problem space of SSO. If you already have a way of solving this, you can still apply this when using this SSO solution.
Is it possible to just take and use (and modify) this solution, or you have some specific licence requirements on in?
The AJAX part of this solution uses Javeline Platform, which is LGPL licensed.
The rest of the software (including all of the PHP code) is in public domain and can be used freely. enjoy
Hi, good tutorial. Based on this one I coded my own SSO server. Just one suggestion to yours solution it’s better to store client token in session, because cookies on client can be disabled. And it’s a good idea to use HTTPS
between SSO server and Broker
Great tutorial! Thanxs
Hi Arnold,
first of all, thanks for the nice tutorial.
Nevertheless, I do have a question. In the source code I came across the checksum generating functions and figured that you are using the $_SERVER['REMOTE_ADDR'] var for that. Now my question is: Why? Doesn’t that prevent cross-server-SSO-solutions?
Thanks,
Stefan.
Hi Stefan,
$_SERVER['REMOTE_ADDR'] is the IP address of the client. It is used to prevent session hijacking. It doesn’t ruin cross-server SSO.
Hi !
I can’t setup server SSO. Server error. Can You send full source code and guide detail about SSO ?
Thanks
Hi,
Iam getting curl_init() error , when iam using download files of SSO are using in local system.
Please help me.
Ram, are you sure that you have the curl extension? If so, post the exact PHP error and we’ll have a look.
Hi Arnold Daniels!
I can’t setup SSO. I have an error:
Fatal error: Uncaught exception ‘Exception’ with message ‘SSO failure: Not attached’ in C:\AppServ\www\SSO\broker\sso.php:161 Stack trace: #0 C:\AppServ\www\SSO\broker\index.php(5): SingleSignOn_Broker->getInfo() #1 {main} thrown in C:\AppServ\www\SSO\broker\sso.php on line 161
I use Apache server & PHP 5.2.6. Please help me fix it.
Thanks so much.
Hi Rosa,
This won’t work on Windows since it uses symlinks. You could make it work on Windows by rewriting server/sso.php to work without symlinks. Look at lines 132/133 and function sessionStart().
I’m sorry I can’t help you any further. Good luck.
- Arnold
Hi Arnold Daniels,
- I fixed error above by change row 205 in borker/sso.php:
CURLOPT_COOKIE -> CURLOPT_COOKIESESSION.Is it OK?
- Now I get a error at value $sso->getInfo(). When log-in, value $sso->getInfo() in login.php is Array but it redirect index.php by header function (row 9 at login.php), $sso->getInfo() is Blank. So I can’t log-in successful.Why $sso->getInfo() is don’t save???
Can you help me check it? I only change your code as above.
Thanks,
Rosa
Hi Rosa,
No that is not right at all. The issue is not with the broker, so there is no need to change that code. You’re not not getting the previous error because the broker isn’t working correctly anymore.
At line 132/133 of server/sso.php the program creates a symlink. Since Windows doesn’t support symlinks, the broker session id is not being attached (=symlinked to) to the client session id.
You need to replace the use of symlinks by an alternative solution. For instance you can create a file with the name of the broker session id and write the client session id in it. In function sessionStart() you than need to readout that file and use it as session id. Something like:
This really is all the support I’m willing to give on this matter. Otherwise please switch to a linux based system.
This exactly what I was looking for my site http://www.ramanandi.org .
I have a social network and a matrimonial site, I use symfony, and I need to share the userbase and a central authentication system.
I think, it would be really helpful
Thanks
Thanks for your good sample.
It’s work fine , but don’t know why I can’t use session_start()
on my page !?
It will bring out crash , is it normal situation ?
A program should never crash, so that is not normal.
(I’ll talk to yancey and add comments if that is useful)
Hi Arnold Daniels!
I can’t setup SSO. I have an error:
Fatal error: Uncaught exception ‘Exception’ with message ‘SSO failure: ‘ in /var/www/SSO/broker/sso.php:161 Stack trace: #0 /var/www/SSO/broker/index.php(5): SingleSignOn_Broker->getInfo() #1 {main} thrown in /var/www/SSO/broker/sso.php on line 161
I use Apache server & PHP 5. Please help me fix it.
Thanks so much.
Hi,
Thanks for this great article, very useful to me. I will try it and give feedback here.
Thanks again.
Hi Bab,
On line 161 of broker/sso.php, the response of the server is checked. The exception that is thrown on a non-200 status is not really clear though.
Please replace the line 161 by:
That should give you a clue what’s going wrong.
Thanks Arnold’s
Thanks for your help
Thanks Arnold for such a nice piece of art:D
I’m trying to run it in Windows changing the symlink for a file as you said in #17 to Rosa but I don’t know how to get the $broker_session_file var.
Thanks in advance
Rob
Hi Arnold,
Here’s the error message I get :
Fatal error: Uncaught exception ‘Exception’ with message ‘SSO failure: The server responded with a 406 status1: “Not attached”.’ in /var/www/SSO/broker/sso.php:162 Stack trace: #0 /var/www/SSO/broker/index.php(5): SingleSignOn_Broker->getInfo() #1 {main} thrown in /var/www/SSO/broker/sso.php on line 162
Can you please help
Rob: Sorry for responding so late. The $broker_session_file var can be determined from the session id that the broker send. It could be something like
In that case you should save the client session id (line 132/133) as
David: Not attached means that PHP failed to create the symlink in function ‘attach()’ of server/sso.php.
Windows Vista and Server 2008 appear to have symlink support. In PHP 5.3 the symlink() function will work for these operation systems.
If you’re running PHP 5.2 with Vista or Server 2008, try using the following function:
Great blog post. Thanks for the download. I am definitely going to adapt it for our code here.
Haven’t run it myself, but I echo Stefan’s question: in server/sso.php, is $_SERVER['REMOTE_ADDR'] the IP address of the client or the broker? Looks to me that it is of the broker, i.e. the IP address of the server that makes the curl call. If so, then it does limit cross-server SSO. My guess is that your demo works because your virtual hosts are all on the same box. Am I wrong in this thinking?
I had a play round with this earlier, and found that it gets rather messy if IPv6 becomes involved. In my case, I was connecting to the broker by IPv4, but the broker and the server had an IPv6 connection between them. This caused a fair bit of confusion with matching up IP addresses and checksums. After hacking away at it, I found the easiest thing to do for now is to force everything to be IPv4 (although, it’d be possible to detect whether the client connection is IPv4, and if so, set the CURL_IPRESOLVE_V4 flag between the broker and the server; if not, use IPv6. Unfortunately, that flag was only introduced in PHP 5.3.0). I guess the problem isn’t IPv6 per se, it’s just the mixing of IPv4 and IPv6. The sooner the whole Internet moves over to IPv6, the better.
Anyway, thanks for this code, it has proven useful, and is now working quite well. I have taken the code a step further and improved the security of logins – specifically, having the username/password handled by a form on the server, rather than the broker, therefore meaning the broker does not get a hold of the password at all. This form is then embedded via an IFRAME into the actual page.
Oh, and while I remember, if anybody wants to access the server via SSL, and you’re getting “The server responded with a 0 status”, it may be due to an invalid/unauthenticated SSL certificate. If so, add this:
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
to the serverCmd routine in sso.php.
Additionally, if you are running your lighttpd as the web server for your server, you may get HTTP 417 errors (see http://redmine.lighttpd.net/issues/1017). To fix that, place:
curl_setopt($curl, CURLOPT_HTTPHEADER, array(’Expect:’) );
within the “if (isset($vars))” block in serverCmd.
Those are some of the issues I’ve had, and managed to sort out. Hopefully it will prove useful for people!
Gerard: Look at the comment ‘// Broker session’ and ‘// User session’. Session id’s of brokers start with ‘SSO-’, therefore the code doesn’t get to the point of $_SERVER['REMOTE_ADDR'] if a broker connects. First the client connects directly to the server and leaves his IP address (in $_SESSION). That IP address is later used to validate the session id of the broker, to make sure the client talking to the broker is the same that talked to the server.
This solution most definitely works cross server. The ‘Binck’ broker is on another server.
Owen Rudge: Thanks for your input Owen. Those are some great comments about issues that might occur. I’m sure that will help a lot of people.
Since I work at a company that make AJAX apps, using an iframe won’t work for us. It really boils down to if both applications have the same owner and if the developer of the broker app can be trusted. If not, than you indeed don’t want to pass the password to the broken.
Perhaps you want to share your code on your blog (I’ll add a link). I’m sure people will be interested.
if (!file_exists($link)) $attached = symlink($targetDir, $file);, its nor working in my server. its always return null.
test: Your code looks flawed. Shouldn’t it be
if (!file_exists($link)) $attached = symlink($targetDir, $link);
Make sure you see E_NOTICE and E_WARNING errors, so you can see why the link is not created.
Ps. This is not a help forum. So plz don’t ask non- and semi-related questions on this blog. Go to http://forums.devnetwork.net instead.
Fatal error: Uncaught exception ‘Exception’ with message ‘SSO failure: The server responded with a 0 status.’ in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\broker\sso.php:161 Stack trace: #0 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\broker\index.php(5): SingleSignOn_Broker->getInfo() #1 {main} thrown in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\broker\sso.php on line 161
Your advice 23 does not help [in fact this you publish exactly same line you want us to replace].
What do you mean in post 27, you want to place this code inside function ‘logout’? I do not think so…
And same about 28 – WHERE you want to place this function?
Garry: I already changed the line of [23] in the source.
Probably the server didn’t really return a 0, but the curl call fails.
Add the following on line 216:
Function ’symlink’ [28], is used on the SSO server. You don’t need [27] if you use [28].
Parse error: syntax error, unexpected T_NEW in /usr/local/apache2/htdocs/nswapps/login/sso/broker/sso.php on line 120
I use Apache server & PHP 4. Please help me fix it.
urgent needed..
I like the SSO server, really interested in using it but the way it works is the slightest bit beyond me, I would like to make a minor change to it where the brokers and the users are all stored in two separate mysql tables. Does anyone know how I would do this or has someone already achieved this and is willing to send me a copy. Thanks.
Yunuz: This code (or any other code I’ve ever posted or will post) won’t work with PHP 4. Upgrade to PHP 5, PHP 4 has been dead for over a year.
Chris: Look at function generateSessionId() and generateAttachChecksum(). The secret phrase is fetch using self::$brokers[$broker]['secret']. You can replace that by a query like “SELECT secret FROM broker WHERE name=’$broker’”.
Further you should replace function login() with something more sophisticated. You can probably replace this with your existing auth login method. Also replace the info() method.
Hi,
I just downloade the file sso.zip and unzip it to my ubuntu server root (ver 9.10). Change the sso server link like this:
public $url = “http://localhost/server/sso.php”;
Run the first time, it said curl_init is undefined, so i update php5-curl using this:
apt-get install php5-curl
The update is successful and then i restart apache2 server.
The next try, i got this error:
Fatal error: Uncaught exception ‘Exception’ with message ‘SSO failure: The server responded with a 406 status: “Not attached”.’ in /var/www/broker/sso.php:162 Stack trace: #0 /var/www/broker/index.php(5): SingleSignOn_Broker->getInfo() #1 {main} thrown in /var/www/broker/sso.php on line 162
Can anyone help me out? any other settings i need to make?
I guess the sso server and the broker on the same machine doesn’t matter, right?
Thank you
ubuntu9: Not attached means that the session id used by the broker is not linked to the session of the client.
Enable error logging (http://nl3.php.net/manual/en/errorfunc.configuration.php) and look at the error_log. You’ll probably see ‘Failed to attach; Symlink wasn’t created’, with one or more warning above it, telling you why the symlink wasn’t created.
—
Also I want to point out that using localhost or a LAN might cause issues. If the broker is on the LAN but the SSO server isn’t, the $_SESSION['client_addr'] is different. The server will respond with ‘Invalid session id’. Since you’re getting a ‘Not attached’ message, this is not the issue in your situation.
Thanks, Arnold for your explanation.
Yes, you are quite correct, localhost should not be used in any case. The actual server name or IP address should be used instead. Deploy both broker and sso server on the same box may cause issue too.
In my case, now i’m using two LAN machines:
1. server1: windows 2003 with curl loaded, used as broker server
2. server2: ubuntu 9.10, used as sso server
in sso.php of the broker, i change sso url like this:
public $url = “http://server2/server/sso.php”
Using firefox 3.5.5, the first try to: http://server1/broker/index.php always result in indefinite redirect. The browsers display something like this:
In the address bar: http://server1///////////broker/index.php
Details of the error:
————————————————————
The page isn’t redirecting properly
Firefox has detected that the server is redirecting the request for this address in a way that will never complete.
* This problem can sometimes be caused by disabling or refusing to accept
cookies.
————————————————————
Look at the apache log file i see:
————————————————————
192.168.84.246 – - [10/Nov/2009:13:10:09 +0700] “GET /broker/index.php HTTP/1.1″ 307 -
192.168.84.246 – - [10/Nov/2009:13:10:09 +0700] “GET //broker/index.php HTTP/1.1″ 307 -
192.168.84.246 – - [10/Nov/2009:13:10:09 +0700] “GET ///broker/index.php HTTP/1.1″ 307 -
192.168.84.246 – - [10/Nov/2009:13:10:09 +0700] “GET ////broker/index.php HTTP/1.1″ 307 -
192.168.84.246 – - [10/Nov/2009:13:10:10 +0700] “GET /////broker/index.php HTTP/1.1″ 307 -
192.168.84.246 – - [10/Nov/2009:13:10:10 +0700] “GET //////broker/index.php HTTP/1.1″ 307 -
192.168.84.246 – - [10/Nov/2009:13:10:10 +0700] “GET ///////broker/index.php HTTP/1.1″ 307 -
192.168.84.246 – - [10/Nov/2009:13:10:10 +0700] “GET ////////broker/index.php HTTP/1.1″ 307 -
192.168.84.246 – - [10/Nov/2009:13:10:10 +0700] “GET /////////broker/index.php HTTP/1.1″ 307 -
192.168.84.246 – - [10/Nov/2009:13:10:10 +0700] “GET //////////broker/index.php HTTP/1.1″ 307 -
192.168.84.246 – - [10/Nov/2009:13:10:10 +0700] “GET ///////////broker/index.php HTTP/1.1″ 307 -
————————————————————
I manually re-enter the URL like this http://server1/broker/index.php
Now the login page showned up.
I have no idea why there are so many redirects here? What can be the reason of this? I appreciate your help
ubuntu9: Try to see what is happening with the Tamper Data or Live HTTP headers plugin. You’re probably being redirected back-and-forth from broker to server. The most obvious reason for this is (as Firefox already suggested), an issue with the session_token cookie.
The additional slash might be because $_SERVER["REQUEST_URI"] starts with a slash, adding the slash in the redirect url. This shouldn’t be a big issue, though see if it helps when you replace line 57 of broker/sso.php with
Thanks Arnold. Your solution worked. $_SERVER["REQUEST_URI"] starts with a slash so there is no need for another slash in header function. Now everything works for me.
To help other developers make this SSO solution work for them, i would like to summarize my experience here:
1. The SSO server must be a unix/linux server. As Arnold said, windows 2008 and vista may work, but i’m not sure.
2. LOCALHOST cannot be used in any case, must be server name or ip address.
3. Change line 57 in broker/sso.php as below (remove the slash before $_SERVER["REQUEST_URI"])
header(”Location: ” . $this->getAttachUrl() . “&redirect=”. urlencode(”http://{$_SERVER["SERVER_NAME"]}{$_SERVER["REQUEST_URI"]}”), true, 307);
Looking at the server/sso.php, i guess this solution will not work if there are many visitors behind a proxy server. Because their IP address will be the same for all (to the outside world). This make the SSO server to treat them as the same client.
Can anyone confirm this? Thanks.
Thank you for your article. Could you write solution for working without symlink()? I tried solution you write in article, but it is not working. I try to do it for 3hours but no success. I have probably permited symlink() on hosting, I tried it on 2 different hosting
jirin: The code is just mend to be an example, not an open source project. However, since there have be so many requests to make this work without symlinks. I’ve modified the code so it can do so. Simply set the links_path property to something like ‘/tmp’ and the SSO server will use files containing the session id, instead of symlinks.
PS. Don’t forget to delete all cookies (broker and server) after changing links_path.
Thank you very much Arnold, it looks working! Once more thanks
Thanks Arnold, I almost have this fully working. However, when a users IP changes, eg. from LAN to Wireless, I get the 406 – Invalid Session Id error. I know this is because the $_SESSION['client_addr'] != the $SERVER['REMOTE_ADDR'] originally stored in the session. What is the best way to reset the client state? I don’t want to have them clear cookies each time this happens. I’m having trouble figuring out where to put the logic as well. Thank you.
Kevin: The IP check is there against session hijacking. You could disable that by simply removing all $_SERVER['REMOTE_ADDR'] entries. They’re not essential for making this SSO method work, but only increase security.
Also, instead of using $_SESSION['client_addr'] to check if a session is initialised (line 86), use $_SESSION['init'] and set that to true (line 103).
Hi Arnold,
Thank you for the help on the REMOTE_ADDR. I am having a separate issue regarding infinite redirects. I find this happens when the client somehow holds a ’session_token’ linked to session ‘a’ using broker ‘x’, and a ’session token’ linked to session ‘b’ using broker ‘y’. How can I protect against this case?
Kevin: Hmm, that’s a bit of an edge-case. I must admit that I didn’t think about that occurring.
I tried to reproduce this, by deleting only the session of the sso-server. In that case the 2 brokers are using different server sessions. However, I’m not able to reproduce the infinite redirecting. Please post how this redirection goes by using something like fiddler or tamper data.
Hi,
I am looking forward to use it. Since it is not not using symlinks so I can easily use this on windows server as well. Very basic question: Do I need seperate server for broker?
Thanks,
Amit
Amit: The server needs to be on a different domain than the brokers. Using a different subdomain like ‘auth.example.com’ for the server and ‘www.example.com’ for the broker, will work as well. The server/brokers can be on a different fiscal server, but don’t need to be.
Arnold,
I see where it checks for $_SESSION['client_addr'] and destroys the session if it’s not set. But I don’t see where this is actually set.
My implementation hits this session_destroy() everytime. Where in the class were you intending to define the ‘client_addr’ session var?
Thanks.
$_SESSION['client_addr'] is set by the client as it creates the session on line 103.
If you are getting ‘Not attached’ each time, the client is either not connecting to the server or the symlink (or link file) isn’t created correctly. Have a look at the previous comments.
I have the client attaching correctly and the symlink is working. The problems seems to be that there is a sessionStart() at the beginning of the attach(). Here within the sessionStart() it never gets to the bottom where it sets the client_addr. It always matches on the session_name() and then fails on the client_addr.
If I just comment this session_destroy() segment out – I’m able to attach just fine.
Hi Arnold,
Firstly, I want to thank you about your SSO implementation.
When I deployed your source code in my local computer, it worked very well.
But It always gets 403 for bidden error when I deploy it to my hosting.
- SSO server: http://service.mio.vn/server/index.
- SSO client: http://mio.vn/customer/login
Any ideas?
Thank you,
I have just modified SSO implementation to make it do not use symlink function by saving data to a table in database.
Firstly, you can create a table named “links”:
Then, you should modify the server class (SingleSignOn_Server) to save data to database instead of saving it to a file.
Just modify 2 functions sessionStart and attach as follow:
After that, you can completely remove links_path property and its initializing in __construct funnction.
Hope it helps
Thiet Doan: The script doesn’t return a 403 http response, so check the URLs and otherwise look at the apache error log.
I guess I don’t see how line 75(server) evaluates false when it is being set every time in the cookie by the broker on line 205(broker). If this evals true everytime (mine does) it will never get to line 103 where the client_addr is set. What am I doing wrong? Should this be evaluating false the first time around?
Ok, I see how it’s supposed to work. It does indeed evaluate false the first time through on the attach. The session appears to be set (the first time through). But the second time the sessionStart() is fired, the $_SESSION[client_addr] is no longer set. Do you know what may cause that?
Mathias: If no session variables are set, the broker probably isn’t using the session file that was created by the client when connecting to server.
On line 85 AND line 103, insert
Use something like tamper data (firefox) or fiddler (windows) to check the HTTP headers. Check the session dir and see if the session file of the broker is a symlink to the session file of client.
Hi Arnold,
First I would like to thank you for your nice work! It’s so great to find this kind of help.
I have a particular question about your single sign on. I would like to implement it on my website to allow my partners to use my API.
At the present time, my partners insert my API on their own website for their own users. But these users have to register and then login when they come to the API pages.
My question is, can I use your single sign on script to allow to my user’s partner to log on once only?
And my second question is, if my partners have their own users registered in their DB, will I have to registered their users first on my own DB before? Or will I have to create accounts on the fly?
I don’t know if I’m clear enough so please let me know,
Thanks again,
Alexandre
Alex: In this example, the SSO-server does all the authentication, though the brokers collect the username and password. That means that a.) the brokers need to be completely trusted (aka your sites). This is probably not the case for partners. And b.) it assumes that the SSO-server holds all user information and the brokers hold none.
If the SSO-brokers hold their own user information, the role of the SSO-server changes. He no longer has to do authentication, the broker can simply tell the server that that user is logged in. The server can tell the next broker, that this user is logged in. For this the SSO-servers needs to know which user of broker A is which user on Broker B.
Example; I’m known as ‘arnolddaniels’ on LinkedIn, but as ‘adaniels_nl’ on Twitter. LinkedIn would tell the SSO-server that ‘arnolddaniels’ has logged in. If I would visit Twitter next, Twitter would as which user is logged in. If the server would reply ‘arnolddaniels’, this would not work.
That whole issue can be overcome by not having the brokers pass a username, but pass an e-mail adress instead. In that case, the server does not have to create any accounts (not at forehand and not on the fly).
Hi Arnold,
Thanks for your answer.
I think I got it. So in my case, if I want to allow my Partners to use the single sign on for their own users, I will need to ask them to import first their users into my own DB (through a CSV file and a simple form in my front site for e.g).
Then, once their users have been added to our DB, I could match them thanks to their email as the ID as per your suggestion.
So finally, User A) will go to Partner site and connect to their own DB during the authentifaction, then once he will come to our API included inside the Partner site, he will be automatically recognized and logged in (so we could save information related to this particular user in our own DB when he will use our API).
This sounds good, but I have another question: How can I have the Partner’s users list always up to date?
I mean, I can’t ask to my Partners to update their user’s list everyday through my website thanks to a .CSV file for e.g… it’s too constraining… Do you have any idea for this?
Alex.
Alex: ehh no… The server doesn’t need to have any account information of the users.
User A will go to Partner X site. He will be redirected to the SSO-server, where a new session is created and attached. Partner X asks if the user is already logged in and the SSO-servers replies ‘no’. User A logs in at Partner X. Partner X sends the e-mail address to the SSO-server. The SSO-server will save this e-mail in the attached session.
Now user A visits Parner Y site. He will be redirected to the SSO-server, where his existing session is attached. Parner Y asks if the user is logged in and the servers replies with the e-mail adress. Parner Y looks up the user in his own DB based on the e-mail adress and logs in the user without asking for a password.
Do know that you need to completely trust all partners. An administrator of any partner can get into any account of any other partner, without having to specify a password. This is due to the fact that logging in to any of the partner sites means you’re logged in to all of the partner sites.
Sorry but I have some difficulties to understand properly the whole process.
When you said:
“Now user A visits Parner Y site. He will be redirected to the SSO-server, where his existing session is attached. Parner Y asks if the user is logged in and the servers replies with the e-mail adress. Parner Y looks up the user in his own DB based on the e-mail adress and logs in the user without asking for a password.”
=> What happens if User A is not in Partner Y DB?
The thing is, all my partners will have different DB (obviously) with different users so how User A could connect to Partner Y site although User A is a user of Partner X?
Also my main goal is to allow the registered users of each of my partners to connect to my own DB / users system when they will use my API without having to sign in again (twice: first on the partner home page, and then when they come to our API included in Partner’s website pages).
But my partners won’t accept to share their users credentials with the others partners…
Actually, I though I could use your Single sign on like the following procedure:
- http://getsatisfaction.com/developers/fastpass
- http://getsatisfaction.com/developers/fastpass_technical
Is it possible?
Thanks again, and sorry for my misunderstanding,
Alexandre
Alex: Remember, the trick of this whole method is shared sessions. The broker (the server of your partner site) can use the same session as the client, therefore the broker can do anything the client (user) would normally do. This can be logging in, but also registering, adding a product in a shopping cart, enabling a service, etc.
After logging in on the partner site, the broker might tell the server that user ’somebody@example.com’ has logged in. The server should return whether or not the user exists (as HTTP response). If the user does not exist, the broker can send the user information to the server, which can create a user OR the broker can simply redirect the client to register himself. If the sign-on is only 1-way, simply leave out the part where the broker requests the e-mail address of the logged in user.
Also, if I understand correctly, sessions shouldn’t be shared between brokers. The best way to solve that is to make 1 subdomain per broker, eg:
http://partner-x.example.com
http://partner-y.example.com
This can be done by a virtual host with ‘ServerAlias *.example.com’. Than get the broker name from $_SERVER['HTTP_HOST'] instead of from $_REQUEST['broker'].
Hi Arnold,
First I would like to thank you for your great work.
I have two domain name like http://testsso.com/test/ and http://session.com/session/ how i will configure?.I am new to this concept can you please explain.I got the error.i am using php 5.2.3 version and apache
Uncaught exception ‘Exception’ with message ‘SSO failure: The server responded with a 404 status: “Object not found! Object not found! The requested URL was not found on this server. If you entered the URL manually please check your spelling and try again. If you think this is a server error,
Thanks
Sriman
Sriman: The url to the SSO server (in broker/sso.php on line 16) is not configured correctly.
Hi Arnold,
Thanks for your help,After i give proper url i got the
Uncaught exception ‘Exception’ with message ‘SSO failure: The server responded with a 406 status: “Not attached”.’ in C:\xampp\htdocs\phpsvn\test\sso.php:161 Stack trace: #0 C:\xampp\htdocs\phpsvn\test\login.php(8): SingleSignOn_Broker->getInfo() #1 {main} thrown in C:\xampp\htdocs\phpsvn\test\sso.php on line 161.why its coming error.whats the problem?can you help me.
Thanks
Sriman
Sriman: Please read the comments of the properties of the class SingleSignOn_Broker and class SingleSignOn_Server. Most of them are settings. You should configuring them. Also read the comments below the article. In there this question is already answered.
In this case, since you are using Windows, you can’t use symlinks. Instead use normal files for attaching by setting $links_path ( server/sso.php line 15) to some kind of tempdir.
Hi Arnold,
First of all Wishing you a Merry Christmas…..
still i have big doubt that is i login to gmail account… now go to my localhost give that gmail url as public url in broker sso.php and url not specify the any php file just url of gmail.i configure the ur code in my localhost.is it possible to autologin in my site when i login gmail……kindly give some clarification of example….please.
Thanks
Sriman
sriman: This is an example of how to set up your own Single Sign-On system, with your own user data. It has absolutely nothing to do with Google accounts / GMail or those kind of things.
To validate google users, you need to use OpenID. See http://code.google.com/intl/nl/apis/accounts/docs/OpenID.html
sriman: The download is not a install and configure application. This is an example showing how to implement SSO in your own application. Installing this software on your server should give you the exact same functionality as the demos. You can log in with the users, set on server/sso.php line 43.
You need write your own authentication implementation, replacing login() and info().
Again, this is just an example, not a full fledged SSO solution. If you need that, look at simpleSAMLphp.
This is all I can say about this. Just read the article and comments carefully. You’ve asked nothing that is not explained in there.
Very informative article. This just made things quite clear. Specially i like the part when images have been explained using http response codes.
Hi,
Interesting article. One point I don’t quite understand is what information a second broker is passing to the SSO server which allows it to be linked to the session of the first broker. Am I correct in thinking that the client IP address is used to identify the client on multiple domains? Thus if the IP address of a logged in client is known then security is compromised?
Thanks,
Paul
Paul: No, the IP is purely against session hijacking and can be left out.
Read the article again and look at the images more closely. Don’t try to deduce the working by looking at the code. The trick lies in the broker token that is issued by the broker, than passed to the client, which passed it to the server. The server knows who the client is by the session cookie.
Does anyone have any idea of how to customize this so that it uses a database to store brokers, users, and sessions. Need it to be able to easily scale to support anything from 3 sites to 50 sites and an unlimited number of users.
Thank you, it really works, We’ve implemented your code on program using CI framework. Still wondering if it can be used with Moodle.
Hi Arnorld,
it works fine on my localhost, nice share..
@nizar : it would be nice if you could share your implementation on CI application…
Hi Arnold,
I copied ur server/sso.php to sso.sahooshare.com and broker directory contents to http://www.konnectp.com, but still it won’t work.
It displays the below error when i try to access http://www.konnectp.com.
Fatal error: Uncaught exception ‘Exception’ with message ‘SSO failure: HTTP request to server failed. couldn’t connect to host’ in /hsphere/local/home/sarada/konnectp.com/sso.php:216 Stack trace: #0 /hsphere/local/home/sarada/konnectp.com/sso.php(155): SingleSignOn_Broker->serverCmd(’info’) #1 /hsphere/local/home/sarada/konnectp.com/index.php(7): SingleSignOn_Broker->getInfo() #2 {main} thrown in /hsphere/local/home/sarada/konnectp.com/sso.php on line 216
broker= http://www.konnectp.com/index.php
sso server= http://sso.sahooshare.com/sso.php
but still it shows the above error.
Please help me.
Thanks in advance.
Sarada The broker is unable to connect to the server. Make sure you have the right URL in broker/sso.php on line 16. Check if there is a firewall in place blocking outbound traffic on port 80.
Hello Arnold,
I have given correct url in my broker. U can see as below.
public $pass401=false;
public $url= “http://sso.sahooshare.com/sso.php”;
public $broker = “LYNX”;
public $secret = “klm345″;
I can able to access the above server url, its working.
But as you said how can i know whther there is a firewall which blocks port 80 or not .
Could you please help me.
Thanks in advance.
Sarada This is a system administration problem, not a software issue. If you’re not the sysadmin, please consult your sysadmin. If you are the sysadmin, you should know how to solve this.
Hi Arnold,
It was some system issue. I consult the System admin and it got fixed. Now it is working.
You can see the demo at @ http://www.konnectp.com
Thanks.
Hi Arnold,
How to implement the single sign in my site.
give me proper explanation in step by step. i am new to this concept .
Give proper response is appreciated.
Thank
Jack
Hi Jack ,
This is about as step-by-step as it’s going to get here. Make sure you read the article carfully, so you understand the concept behind the code.
You might want to take 3 steps for implementing the SSO solution in your own site:
1.) Download the code from GitHub and get it working, as is, on your server.
2.) Replace line 140 of server/sso.php with a method that check the referentials against your database. Replace function info() to get the user info from the DB.
3.) Copy/paste line 1 to 10 from broker/index.php into your own site. Replace broker/login.php with your own login screen.
If you need more help, try one of the many PHP forums like http://forums.devnetwork.net
Good luck
Hi Arnold Daniels,
Thanks for your help.I follow the what your mention.
If any doubts kindly help me.
Thanks
Jack
Hi Arnold,
I have started to implement SSO in my http://www.test.com.
1. I just down load and copy the your folder in to my test.com.
2.I made changes that in server/sso.php for credential and get user info based on userName and password.
3. you said Copy/paste line 1 to 10 from broker/index.php into your own site where i am going to copy the that 10 lines?
4.i have copy that login screen in my own.
could you please help me to finish the task…
Thanks
Jack
Jack: Some advise in advance, after each step, make sure that the app is working properly.
Line 1 to 10 from broker/index.php checks if a user is logged in. If that is not the case it redirects the client to login.php. If your site doesn’t require a user to be logged in, you don’t need it.
Hi Aranold,
Thanks for your advise. App is working fine and i integrate your code in my site and logged in my site of your broker login and after that i refresh your demo http://sso-alex.adaniels.nl/index.php its logging in with out log of again and if log out your demo site in mysite broker also logout.
So i reached the single sign on or i need to do any thing else……
Kindly explain to finish the task….
Thanks
Jack
Jack I don’t understand your last comment.
In the end you should be using your own SSO-server and SSO-brokers. The brokers are your websites which share their authentication. Based on the article and my previous comments you should be able to implement your own SSO solution.
Please remember that this is not a help forum.
Hi Arnold,
I have downloaded the files from github and ran it on Linux and Windows, but I couldn’t make it work properly. Maybe I’m missing something, but there’s a strange problem.
Suppose that you copy the directory broker with a new name like broker2. Now it’s supposed to have SSO between /broker and /broker2 but it’s both of them work separately and once logged in /broker , there’s no SSO in /broker2
The most strange part is that on windows they work completely separate, but on Linux once you log in /broker and then open a page to /broker2 , you will be logged out of /broker !
Thanks
Hi Arnold,
i have made changes as mentioned above.
i made changes as
server/sso.php
array(’secret’=>”abc123″),
‘BINCK’ => array(’secret’=>”xyz789″),
‘UZZA’ => array(’secret’=>”rino222″),
‘AJAX’ => array(’secret’=>”amsterdam”),
‘LYNX’ => array(’secret’=>”klm345″),
);
/**
* Information of the users.
* This should be data in a database.
*
* @var array
*/
protected static $users =”select * from mdl_user where username=’$username’ AND password=’$password’”;
and
IN BROKER/sso.php as
<?php
/**
* Helper class for broker of single sign-on
*/
class SingleSignOn_Broker
{
/**
* Pass 401 http response of the server to the client
*/
public $pass401=false;
/**
* Url of SSO server
* @var string
*/
public $url = "http://localhost:81/broker/sso.php";
/**
* My identifier, given by SSO provider.
* @var string
*/
public $broker = "LYNX";
/**
* My secret word, given by SSO provider.
* @var string
*/
public $secret = "klm345";
/**
i am getting login page tats all.. nothing is working
Hi,
Thanks for a great sso implementation.
I did implement it with database(actually using webservices provided by one of our .net site) in my local server and every thing works great.
The problem is when I uploaded it to live server.the first time i load the site, it goes directly to my sso_server.php file(seems it redirects physically ).
second time i load the site, i get 406 error.
IF i clear my cookies, the same thing happens.
Is it some kind of settings i need to do ffor production?
we have a linux dedicated box with apache and php 5.12
have mamp in may local computer on mac.
Other thing.
I do get 406 error in my local computer some time. I think it’s when I don’t logout and local cookie expires. Guess something with session expire. butright now i am really looking to make this thing work on my real server.
Thanks for a great implementation.
Fatal error: Uncaught exception ‘Exception’ with message ‘SSO failure: The server responded with a 406 status: “Not attached”.’ in C:\apache2triad\htdocs\SSO\sso\broker\sso.php:161 Stack trace: #0 C:\apache2triad\htdocs\SSO\sso\broker\index.php(5): SingleSignOn_Broker->getInfo() #1 {main} thrown in C:\apache2triad\htdocs\SSO\sso\broker\sso.php on line 161
please help me…
i use windows 7 and apache2triad with PHP 5.1.2
thanks before…
David Make sure that the brokers are configured with different identifiers.
vij Changing $users to a database query won’t work. This example doesn’t have database support. You need to add that yourself. See comment 87.
Sam Make sure that the symlinks to the session files are created correctly. Have a look at the remarks in some of these comments about ‘Not attached’ issues. Ask again if you’re unable to fix it.
dacus Try manually setting $links_path in broker/sso.php and make sure you can write to that path.
Hi Arnold,
Well my windows machine creates 2 files for 2 brokers I have set ( using the same broker name ) as follows :
1. sess_SSO-LYNX-dfe09fcdc0a9e9d7f31aa39d15e9f794-9d0d2a9eb1468eb324502615d9a427dd
2. sess_SSO-LYNX-7488f04b107e05e943d027531a871688-172c95da16538918869b814bb0fae579
at the time I just visit the broker’s page. when I login, the content of the session files changes and includes information. But the wrong part is that when I login in /broker1 it only changes one of the session files and when I refresh the page on /broker2 it still thinks that I have not logged in!
I just downloaded the files again and made no changes on the files. I have no idea why it’s not working properly on my machine. Maybe it needs some PHP settings that are not set on my machine!
Thank you in advance for your kind help
hi arnold,
now , i got it
Warning: SimpleXMLElement::__construct(): Entity: line 1: parser error : Start tag expected, ‘__construct(’1′) #1 C:\apache2triad\htdocs\SSO\sso\broker\sso.php(158): SingleSignOn_Broker->parseInfo(true) #2 C:\apache2triad\htdocs\SSO\sso\broker\index.php(5): SingleSignOn_Broker->getInfo() #3 {main} thrown in C:\apache2triad\htdocs\SSO\sso\broker\sso.php on line 143
thanks
David Do not use the same name for multiple brokers. A name (identifier) needs to be unique per broker.
Those sess_SSO files should be symlinks to the same session file. Please check if this is the case. If this is not the case, check if the attach request is done (using fiddler, tamper-data, live-http-headers, or something similar).
dacus The info function in server/sso.php isn’t outputting valid XML or you output other (debugging) text.
Hi,
Though it works on server( I changed the links path location to save it in a httpdocs folder. using db slow downs. )seems it was permission issue.
Now the problem
I don’t think I can explain what’s going wrong with me, but why do we have thisin broker constructor, inside $auto_attach loop.
header(”Location: ” . $this->getAttachUrl() . “&redirect=”. urlencode(”http://{$_SERVER["SERVER_NAME"]}
I have ajax request posting some variable. The issue is when I don’t logout, or say I visited the page after some time(it could be cookie expire time), it popsup saying ( the server is redirecting, would you like to send the form data you sent). This is because I send post data to a page, and when it tries to auto attach it the redirection call blocks it askign to send form data. This is only for ajax requests.
Surprisingly, this wont happen all the time. it’s just if I visit one page and come back after some time. Secondly it’s not consistent too.
any clue?
Sam When using AJAX, don’t use auto attach. Using SingleSignOn_Broker as a controller, assumes you are doing ajax. Line 222 to 229 sets $auto_attach to false and enables 401 passing.
With AJAX, the Javascript client should check if the token cookie exists. If not, it should attach by getting the attach URL and loading it in an
tag. To make sure that you don’t get ‘Not attached’ errors, the lifetime of the token-cookie needs to be smaller than that of the session.
Alternatively you can pass 406 results, like 401 results are passed. On a 406 reattach and try again. Make sure you only do this retrying once, not to create a dead-loop.
Make sure you’ve read the ‘Using AJAX / Rich Internet Application’ paragraph.
Thanks Arnold,
I appreciate your responses. I am getting close.
I have one issue though. If I do not have a session attached to a broker, and I do a post request, firefox will popup with “This web page is being redirected to a new location. Would you like to resend the form data you have typed to the new location?”
It’s again because of that 307 redirect. Can’t I use curl request to attach instead of header().
Thanks
Hi Arnold,
Thank you for this great article. I’ve implemented my own SSO Client / Broker / Server on Symfony (largely) inspired by yours.
So far, everything’s fine ! I’ve used HTTPS along the whole process to ensure there won’t be any session hijack.
Again, thanks a lot for this great explaination.
Sam No you can’t use curl to attach. The broker doesn’t know the session of the client at the SSO server. Otherwise this whole method would not be needed in the first place. Attaching always takes place through the client (browser).
Attach on first visit on your website. Remember that attaching is not the same as logging in. It simply means that you have a session running at the SSO server and that the broker is attached to it. You can use it to log in at any time.
OR
Don’t use a redirect (using header) to attach. Instead you can place an
node. Use AJAX to get the source of the image with the getAttachUrl() method. Use Javascript to write an
node.
Hi arnold, thanx for the download. Im not getting any errors while accessing the two different brokers from my client but they are being independent. when i login at one broker and refresh the other broker page it still shows the login page, not showing the user info. im not able to understand where it is going wrong. please help.
Remo have a look at the cookies from the SSO server. See if the session file is created correctly and if there is symlink linking to it.
Also there are issues when running the broker or server on your local computer.
hi arnold, thnx for your sso source code..but i want to connect user name to database(mysql),can you halp me?thnx before..:)
Hi,
I have been used your solution with one of my zend framework project.
I had o customize your solution to use with zend framework.
It was working with php 5.2 but whenever I have upgraded my php version 5.3 it is not working. I have been debug your source code I don’t find anything to create problem with php 5.3.
It is now all the time create new session and session expire for every request.
Do you think is there anything which will not work with php 5.3? I am looking forward your suggestion
thanks
Raju Mazumer
I have the same proble like David. The script is running on linux server – php 5.2.6
Where is the problem ?
please, help me.
thanks
Marty Not attached means that PHP failed to create the symlink in function ‘attach()’ of server/sso.php. With a bit of PHP skills you should be able to figure out why. First of all check the HTTP requests that the client does (using firebug) and see if it calls server/sso.php in the first place.
Good luck
Where I check HTTP requests, is it Firebug->Net ? But there is only GET sso-broker.web.com
I can try it, what Thiet Doan wrote(MySQL without symlink), but there is still the same error.
At the first visit I am redirected to sso server with this error :
Warning: file_exists() [function.file-exists]: open_basedir restriction in effect. File(/var/lib/php5/sess_SSO-BINCK-8acf06bc3a44412293e1d0bc5fae5146-44158a9d368cd1ff913349943e63a204) is not within the allowed path(s): (/home/www/web.com:/tmp) in /home/www/web.com/sso-server/sso.php on line 170
Fatal error: Failed to attach; Symlink wasn’t created. in /home/www/web.com/sso-server/sso.php on line 171
Thanks for advice
Marty open_basedir is a PHP setting that a (crappy) shared hosting might set to prevent you from accessing the session files. You can do 2 things:
1.) Set $links_path in server/sso.php. This forces the SSO server to use handle attached sessions himself instead of using symlinks.
2.) Store your sessions in an alternative (assessable) path by setting session.save_path. You can do this in an .htaccess file
In both cases make sure that the path is not accessible for your website visitors.
Arnold, Thanks for this great framework!
I’ve used it to glue Wordpress, TYPO3, Scuttle, MyBB, and MediaWiki together by using LDAP authentication against Active Directory. I wrote authentication plugins for every application that use their own SSOProvider. Now our intranet users only need to authenticate once!
Btw, I had to set our cookie timeout to 8h via session.gc_maxlifetime = 28800 so that the users don’t have to login again after 24 minutes (PHP’s default value).
Hi Arnold, thanks for this great tuts. Have a question.
When the first visit broker sends a redirect to the server.
Would my SEO will be affected when implementing it to my sites? because I’m planning to put the login form on the index page.
Please advice.
Thanks
John First of I’m not an SEO expert in any form. I guess it depends on how you implement this. If you implement is as described above I’d say yes. Google probably doesn’t like to be ping ponged around.
An option is not to directly attach when a client visits your site. Instead when a user tries to log in, first save his username/password in a session and redirect to attach. After the client is attached and redirected back to the broker, let the broker authenticate the user.
Another option is to skip the redirecting completely and solve this with javascript. How to do this is described above. This will work if your login form uses AJAX, but also with normal HTML forms.
Yo man,
You doing a very good job..answering all questions over and over again..
I really appreciate your effort on helping other ppl, even though, some of the question is already answered by you previously..
Thanks again mate!
I’m trying to wrap my head around the code you’ve made.
I’ve implemented the code (ajax version) and altered brokers/server to comply with my backend.
I get logged in (well, it returns 1 when i use the correct credentials, but no cookies or sessions are saved on the client side. Is this how it should work?
How can I check if a user is logged in for all services, if not a cookie/session is set? Seems kinda redundant to check the sso server for every service on one page.
Some more info:
I am not using the jaml thingy, it wouldnt work, so i made a simple login form and ajax script instead.
Hm, if I load the class with true
$ctl = new SingleSignOn_Broker(true);
a session cookie is created.
but, i get a 307 temporary redirect on the ajax request, and before the redirect happens, i get a prompt asking me if its ok to send form data..
Alexander The $auto_attach argument means that the server will automatically redirect a client to the server if it detects that the client is not attached. You don’t want this use ajax, so keep this to false.
In javascript you should check if the session_token cookie exists. If not call sso.php?cmd=getAttachUrl with ajax. This will set the session_token cookie and return a url. That url is to the sso-server and can therefore not be requested with ajax. Open that URL in an image instead. As soon as that image is loaded, the client is attached and the broker can make requests to the server.
Note that session_token has nothing to do with PHP sessions. This example stores no information about the client on the broker. There is no reason why you can’t do that if you wish. You need to write that yourself though
.
About checking with the SSO server. Note that the server will not push any information to the SSO broker. This is strictly a polling service. This means that an SSO broker can know that a client has logged off on a different broker by asking the server. If you don’t care about single sign-off, just call getInfo() once and store it in a session on the broker.
hi. Arnold
when logined http://sso-alex.jasny.net/index.php ,
how to generated shanghai@sso-binck.dutchc5 cookie?
My English is bad, do not know whether what I mean。
Thanks !
hucs You don’t, that not possible and not needed. Each broker has it’s own cookie. The session cookie is from sso-server.jasny.net. Please read the article again. It seems like you’re missing the point.
Great tip! Thanks!
Good. I just try to write an SSO application for several decentralized web applications. Each application will be located in different and independent domain if it’s possible, and they will use the same SSO-application to verify and authenticate the user. I think your solution is good, but may it will not suitable for this situation. In your system, if I want to sign-up any application, I need to input user information for each one, and I just think it’s possible to use an central user validation system, and restore one copy of the information of the user. Seems your system doesn’t work for it. So..do you have any good ideas? Would like to know it if you can write email to me. well I wish!
Good luck!
Silver The method described here does exactly what you want (I think). Only the SSO-server contains the information about the user. The SSO-brokers will communicate to the SSO-server continuously.
In my example the SSO-server has only 2 API calls: login and getInfo. However, after you’ve attached you can do all kinds of things. Push user data, create a cart that works across all brokers, etc. The sky is the limit
.
Best way to think about it is a shared session + shared DB across different domains/systems.
Yeah, you are right. Thanks for your message. I am still working on my own SSO-Library. Let me tell you what’s my idea, and this is first part of it. You know that I think there are four different situation to be meet when to make a share user validation system. (note, in the context, “application” is any application to use “sso-server” to authenticate users)
1. All applications are on the same domain, so a local Library is good enough.
2. All applications will be located in different sub domains of the same domain. Need a SSO server.
3. All applications will be located in different domains. Need a SSO server.
4. Hyper-one involves any of the situation above. (?)
And in each situation, the first things’ first is not how to communicate with others, but how do you do with the architecture of that system. I mean, how do you make it works for these applications, and make it more effective and security? I think there are two way to put the user information across different application:
1. Storing all different user information in the same server, so when the application need to know the information, it will need to get those user information from sso-server.
2. Just storing the share part of user information, I mean “username, password, email validation, recovery question && answer, location”, and any other user information will be stored in its own application scope.
Which one is good? I think the first one is simply not good, because when the application need to know any part of the user information, it must use HTTP-REMOTE-CALL/SOAP to get the information from sso-server, it will be more heavy and slow.
The second one is good and simple, the sso-server will be accessed only in register/login/recovery/change password. The any other part of user profile will be stored in the application, and the application will load it from its own scope, so it needn’t to use HTTP-REMOTE-CALL/SOAP or else likes. (What’s google account’s idea?)
What’s your idea?
(BTW, I take my own consideration of that problem, and want to know your idea well if you are willing and free to tell me. Anyway like to learn from you, if luckily for me. To be continued. The next part – I want to discuss the communication way in different situation – register/login/recovery password/change password/even more)
Silver About the 4 situations: You only need to use an SSO-server if the applications are different domains. If the applications are on the same domain, you can simply have a single cookie.
Where to store what information? That completely depends on your situation. All the information you need across applications, should be supplied by the SSO-server. This includes volatile data (sessions) as well as non-volatile data (database). Data that is specific to 1 app, can be stored by that app.
Google does not do SSO, they only do shared authentication. If I’m logged into iGoogle and goto YouTube, I still need to login there. OpenID covers shared authentication.
Thank you very much. Very appreciate your works, and I learned a lot from it. Thanks again. :/
Hi Arnold,
i’ve try ur work with different domain, my config broker
public $url = “http://mygoogleconnect.tld/jasny/server/sso.php”;
and i tested with url
http://mytwitterclient.tld/jasny/broker/
why phpsession not generated only session_token, can u pleaz help me
thanx
zapatista The broker doesn’t has a session, only the server has a session. Any information you store in a session on the broker is *not* shared with other brokers.
Also read comment #129
On login page, How can access to $_SESSION['username']?
williamjlp Please read the previous comments. There is no session on the brokers. You need to request the username from the SSO server.
@Arnold, thanks for your nice tutorial…
)
I have some question. I hope you can answer them :
1. I get task to build a system that can handle (using SSO) some domain that have some different database server. what must I do to that. must I move all of the user information from all database server to just one database server?can I use LDAP to implement that purpose? (I’m sorry, I’m newbie
2. can you give me some advice about framework in PHP for that purpose ?
thanks alot for your answer..
raudy 1. The SSO server should hold all login credentials. The broker should not hold that information. You can do authentication anyway you are doing it now. Using a MySQL db is most common, but LDAP is possible as well.
2. There is no framework I know that has this (or something similar) implemented. Zend Framework could be easily extended to have this feature. You will need to program that yourself though.
Good luck
Hi Arnold Daniels,
Your SSO is very much useful for our site(s). But need a small clarification from you. As in earlier post somebody also asked that how to display/print SESSION Value (Username, though which was used for logged in). You given reply stating that use SSO Sever to call session variable.
But i’m unable to retrieve user information from Server SSO. Can you please give a brief note and solution how to call the user details or session from Server SSO.
If u can explain it is very much useful for me as well as somany users using this script.
Regards
Pavan
Pavan Katravalli Well to be honest, the main article tries to explain just that.
There is 1 session, which lives on the SSO server. Let’s say that the broker would know the session id of the client, the broker could act like the client. However since the session id is in a cookie a another domain, the broker has no way to fetch that session id.
Instead, the broker will tell the client to please tell the server that he (the broker) is privileged to act on behalf of the client. The server will respect that, allow the broker to use the session on the server. That’s the basic trick.
Any calls that the client would normally make directly to a website regarding a session, like logging in, adding products to a cart, etc, can now be done by the broker instead. Since the broker is a machine and not a human, the server should return XML of JSON instead of HTML.
That’s all there is to it
Hi Arnold Daniels,
Thanks for your reply and I understand what you are saying but unable to retrieve and print the user session info from server. Can you please give simple example that how to call and print user data. For example, If login with a username “katravalli” and password “abc123″….. after login I would like to welcome the user something like “Welcome Katravalli”…. Here is my problem…. I’m unable to print Username after welcome…. unable to call from server sso…
Hope you got my point…. can u pls give simple example how it is.. and how to call…!!!!
regards
pavan
The client sends the login credentials to the broker. The broker sends them to server. It is just the middle man.
You should not see the broker as a special kind of server. The broker holds no information. You can see it as a special kind of client. Therefore it needs to request any information from the server using an HTTP request, just like a regular client would.
In short: If the broker wants to print the name of the user, it sends an HTTP request to the server asking the name (and perhaps more user details).