Simple Single Sign-On for PHP (Ajax compatible)

by Arnold Daniels on 04/18/2009

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.
No 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.

Don’t be square, please share!

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

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.

Arnold Daniels

I've spend a big part of my life behind a computer, learning about databases (MySQL), programming (PHP) and system administration (Linux). Currently I playing with HTML5, jquery and node.js.

More Posts

Follow Me:
TwitterLinkedIn

There are 239 comments in this article:

  1. 18 April 2009Daniel says:

    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?

    ReplyReply
  2. 18 April 2009FACORAT Fabrice says:

    can be useful for someone willing to use SSO in his enterprise, for example between different intranet/extranet solutions.

    ReplyReply
  3. 20 April 2009caleng says:

    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.

    ReplyReply
  4. 20 April 2009Arnold Daniels says:

    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.

    ReplyReply
  5. 18 May 2009onge says:

    Is it possible to just take and use (and modify) this solution, or you have some specific licence requirements on in?

    ReplyReply
  6. 19 May 2009Arnold Daniels says:

    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 ;)

    ReplyReply
  7. 25 May 2009woras says:

    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

    ReplyReply
  8. 26 May 2009Hermes Alves says:

    Great tutorial! Thanxs ;)

    ReplyReply
  9. 10 June 2009Stefan says:

    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.

    ReplyReply
  10. 11 June 2009Arnold Daniels says:

    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.

    ReplyReply
  11. 23 June 2009Thanh says:

    Hi !
    I can’t setup server SSO. Server error. Can You send full source code and guide detail about SSO ?
    Thanks

    ReplyReply
  12. 26 June 2009Ram says:

    Hi,

    Iam getting curl_init() error , when iam using download files of SSO are using in local system.

    Please help me.

    ReplyReply
  13. 26 June 2009Arnold Daniels says:

    Ram, are you sure that you have the curl extension? If so, post the exact PHP error and we’ll have a look.

    ReplyReply
  14. 1 July 2009Rosa says:

    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.

    ReplyReply
  15. 1 July 2009Arnold Daniels says:

    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

    ReplyReply
  16. 6 July 2009Rosa says:

    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

    ReplyReply
  17. 6 July 2009Arnold Daniels says:

    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:

    $client_session = file_get_contents($broker_session_file);
    session_id($client_session);
    session_start();

    This really is all the support I’m willing to give on this matter. Otherwise please switch to a linux based system.

    ReplyReply
  18. 13 July 2009sudhir says:

    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

    ReplyReply
  19. 20 July 2009yancey says:

    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 ?

    ReplyReply
  20. 20 July 2009Arnold Daniels says:

    A program should never crash, so that is not normal.
    (I’ll talk to yancey and add comments if that is useful)

    ReplyReply
  21. 28 July 2009Bab says:

    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.

    ReplyReply
  22. 29 July 2009Azwan says:

    Hi,

    Thanks for this great article, very useful to me. I will try it and give feedback here.

    Thanks again.

    ReplyReply
  23. 29 July 2009Arnold Daniels says:

    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:

      default:  throw new Exception("SSO failure: The server responded with a $ret status" . (!empty($body) ? ': "' . substr(str_replace("\n", " ", trim(strip_tags($body))), 0, 256) .'".' : '.'));
    

    That should give you a clue what’s going wrong.

    ReplyReply
  24. 30 July 2009Bab says:

    Thanks Arnold’s

    Thanks for your help

    ReplyReply
  25. 31 July 2009Rob says:

    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

    ReplyReply
  26. 7 August 2009David says:

    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

    ReplyReply
  27. 7 August 2009Arnold Daniels says:

    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

    $broker_session_file = (session_save_path() ? session_save_path() : sys_get_temp_dir()) . '/broker_' . session_id();
    

    In that case you should save the client session id (line 132/133) as

    $broker_session_file = (session_save_path() ? session_save_path() : sys_get_temp_dir()) . '/broker_' . $this->generateSessionId($_REQUEST['broker'], $_REQUEST['token']);
    if (!file_exists($broker_session_file)) file_put_contents('sess_' . session_id(), $link);
    

    David: Not attached means that PHP failed to create the symlink in function ‘attach()’ of server/sso.php.

    ReplyReply
  28. 8 August 2009Arnold Daniels says:

    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:

    define('SYMLINK_FILE', 0);
    define('SYMLINK_DIR', 1);
    define('SYMLINK_JUNCTION', 2);
    function symlink ($target, $link, $flag = SYMLINK_FILE) {
        switch ($flag) {
           case SYMLINK_DIR: $pswitch = '/d'; break;
           case SYMLINK_JUNCTION: $pswitch = '/j'; break;
           case SYMLINK_FILE:
           default: $pswitch = ''; break;
        }
        // Change / to \ because it will break otherwise.
        $target = str_replace('/', '\\', $target);
        $link = str_replace('/', '\\', $link);
        return exec('mklink ' . $pswitch . ' ' . escapeshellarg($link) . ' ' . escapeshellarg($target));
    }
    
    ReplyReply
  29. 3 September 2009gerard says:

    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?

    ReplyReply
  30. 5 September 2009Owen Rudge says:

    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!

    ReplyReply
  31. 6 September 2009Arnold Daniels says:

    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.

    $ host sso-server.adaniels.nl
    sso-server.adaniels.nl has address 82.94.236.135
    $ host sso-alex.adaniels.nl
    sso-alex.adaniels.nl has address 82.94.236.135
    $ host sso-binck.jasny.net
    sso-binck.jasny.net has address 82.94.182.130
    

    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.

    ReplyReply
  32. 7 October 2009test says:

    if (!file_exists($link)) $attached = symlink($targetDir, $file);, its nor working in my server. its always return null.

    ReplyReply
  33. 8 October 2009Arnold Daniels says:

    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.

    ReplyReply
  34. 13 October 2009Garry says:

    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?

    ReplyReply
  35. 13 October 2009Arnold Daniels says:

    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:

    if (curl_errno($curl) != 0) throw new Exception("SSO failure: HTTP request to server failed. " . curl_error($curl));
    

    Function ‘symlink’ [28], is used on the SSO server. You don’t need [27] if you use [28].

    ReplyReply
  36. 5 November 2009yunuz says:

    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..

    ReplyReply
  37. 5 November 2009Chris says:

    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.

    ReplyReply
  38. 5 November 2009Arnold Daniels says:

    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.

    ReplyReply
  39. 8 November 2009ubuntu9 says:

    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

    ReplyReply
  40. 9 November 2009Arnold Daniels says:

    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.

    ReplyReply
  41. 10 November 2009ubuntu9 says:

    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

    ReplyReply
  42. 10 November 2009Arnold Daniels says:

    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

    header("Location: " . $this->getAttachUrl() . "&redirect=". urlencode("http://{$_SERVER["SERVER_NAME"]}{$_SERVER["REQUEST_URI"]}"), true, 307);
    
    ReplyReply
  43. 12 November 2009ubuntu9 says:

    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.

    ReplyReply
  44. 15 November 2009jirin says:

    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

    ReplyReply
  45. 16 November 2009Arnold Daniels says:

    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.

    ReplyReply
  46. 16 November 2009jirin says:

    Thank you very much Arnold, it looks working! Once more thanks

    ReplyReply
  47. 18 November 2009Kevin says:

    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.

    ReplyReply
  48. 18 November 2009Arnold Daniels says:

    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).

    ReplyReply
  49. 20 November 2009Kevin says:

    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?

    ReplyReply
  50. 21 November 2009Arnold Daniels says:

    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.

    ReplyReply
  51. 27 November 2009Amit says:

    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

    ReplyReply
  52. 27 November 2009Arnold Daniels says:

    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.

    ReplyReply
  53. 4 December 2009Mathias says:

    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.

    ReplyReply
  54. 4 December 2009Arnold Daniels says:

    $_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.

    ReplyReply
  55. 5 December 2009Mathias says:

    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.

    ReplyReply
  56. 5 December 2009Thiet Doan says:

    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,

    ReplyReply
  57. 5 December 2009Thiet Doan says:

    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”:

    CREATE TABLE IF NOT EXISTS `links` (
      `id` int(11) unsigned NOT NULL auto_increment,
      `code` varchar(128) NOT NULL,
      `link` varchar(64) default NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 ;
    

    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:

    protected function sessionStart()
    {
        if ($this->started) return;
        $this->started = true;
        
        // Broker session
        $matches = null;
        if (isset($_REQUEST[session_name()]) && preg_match('/^SSO-(\w*+)-(\w*+)-([a-z0-9]*+)$/', $_REQUEST[session_name()], $matches)) {
            $sid = $_REQUEST[session_name()];
            
            // check the ID existed or not
            $result = $database->query("SELECT `* FROM `links` WHERE `code` = '" . $sid . "'")
            if (isset($result['link'])) {
                session_id($result['link']);
                session_start();
                setcookie(session_name(), "", 1);
            } else {
                session_start();
            }
    
            if (!isset($_SESSION['client_addr'])) {
                session_destroy();
                $this->fail("Not attached");
            }
            
            if ($this->generateSessionId($matches[1], $matches[2], $_SESSION['client_addr']) != $sid) {
                session_destroy();
                $this->fail("Invalid session id");
            }
    
            $this->broker = $matches[1];
            return;
        }
    
        // User session
        session_start();
        if (isset($_SESSION['client_addr']) && $_SESSION['client_addr'] != $_SERVER['REMOTE_ADDR']) session_regenerate_id(true);
        if (!isset($_SESSION['client_addr'])) $_SESSION['client_addr'] = $_SERVER['REMOTE_ADDR'];
    }
    
    public function attach()
    {
        $this->sessionStart();
        
        if (empty($_REQUEST['broker'])) $this->fail("No broker specified");
        if (empty($_REQUEST['token'])) $this->fail("No token specified");
        if (empty($_REQUEST['checksum']) || $this->generateAttachChecksum($_REQUEST['broker'], $_REQUEST['token']) != $_REQUEST['checksum']) $this->fail("Invalid checksum");
    
        $sid = $this->generateSessionId($_REQUEST['broker'], $_REQUEST['token']);
        $result = $database->query("SELECT `* FROM `links` WHERE `code` = '" . $sid . "'")
        if (!isset($result['link'])) {
            $attached = $database->query("INSERT INTO `links`(`code`, `link`) VALUES('" . $sid . "', '" . session_id() . "')");
            if (!$attached) trigger_error("Failed to attach; Symlink wasn't created.", E_USER_ERROR);
        } else {
            $attached = $database->query("UPDATE `links` SET `link` = '" . session_id() . "' WHERE `code` = '" . $sid . "'");
            if (!$attached) trigger_error("Failed to attach; Link file wasn't created.", E_USER_ERROR);
        }
    
        if (isset($_REQUEST['redirect'])) {
            header("Location: " . $_REQUEST['redirect'], true, 307);
            exit;        
        }
        
        // Output an image specially for AJAX apps
        header("Content-Type: image/png");
        readfile("empty.png");
    }
    

    After that, you can completely remove links_path property and its initializing in __construct funnction.

    Hope it helps

    ReplyReply
  58. 7 December 2009Arnold Daniels says:

    Thiet Doan: The script doesn’t return a 403 http response, so check the URLs and otherwise look at the apache error log.

    ReplyReply
  59. 8 December 2009Mathias says:

    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?

    ReplyReply
  60. 8 December 2009Mathias says:

    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?

    ReplyReply
  61. 8 December 2009Arnold Daniels says:

    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

    header('X-SessionId: ' . session_id());
    

    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.

    ReplyReply
  62. 15 December 2009Alex says:

    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

    ReplyReply
  63. 15 December 2009Arnold Daniels says:

    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).

    ReplyReply
  64. 15 December 2009Alex says:

    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.

    ReplyReply
  65. 15 December 2009Arnold Daniels says:

    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.

    ReplyReply
  66. 15 December 2009Alex says:

    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

    ReplyReply
  67. 15 December 2009Arnold Daniels says:

    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'].

    ReplyReply
  68. 23 December 2009sriman says:

    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

    ReplyReply
  69. 23 December 2009Arnold Daniels says:

    Sriman: The url to the SSO server (in broker/sso.php on line 16) is not configured correctly.

    ReplyReply
  70. 23 December 2009sriman says:

    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

    ReplyReply
  71. 23 December 2009Arnold Daniels says:

    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.

    ReplyReply
  72. 24 December 2009sriman says:

    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

    ReplyReply
  73. 24 December 2009Arnold Daniels says:

    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

    ReplyReply
  74. 24 December 2009Arnold Daniels says:

    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.

    ReplyReply
  75. 7 January 2010Crash says:

    Very informative article. This just made things quite clear. Specially i like the part when images have been explained using http response codes.

    ReplyReply
  76. 8 January 2010Paul Harman says:

    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

    ReplyReply
  77. 10 January 2010Arnold Daniels says:

    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.

    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.

    ReplyReply
  78. 17 January 2010Chris says:

    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.

    ReplyReply
  79. 18 January 2010Nizar says:

    Thank you, it really works, We’ve implemented your code on program using CI framework. Still wondering if it can be used with Moodle.

    ReplyReply
  80. 27 January 2010Deni says:

    Hi Arnorld,
    it works fine on my localhost, nice share..
    @nizar : it would be nice if you could share your implementation on CI application…

    ReplyReply
  81. 7 February 2010sarada says:

    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.

    ReplyReply
  82. 8 February 2010Arnold Daniels says:

    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.

    ReplyReply
  83. 8 February 2010sarada says:

    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.

    ReplyReply
  84. 8 February 2010Arnold Daniels says:

    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.

    ReplyReply
  85. 9 February 2010sarada says:

    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.

    ReplyReply
  86. 21 February 2010Jack says:

    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

    ReplyReply
  87. 22 February 2010Arnold Daniels says:

    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

    ReplyReply
  88. 23 February 2010Jack says:

    Hi Arnold Daniels,

    Thanks for your help.I follow the what your mention.
    If any doubts kindly help me.

    Thanks
    Jack

    ReplyReply
  89. 23 February 2010Jack says:

    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

    ReplyReply
  90. 23 February 2010Arnold Daniels says:

    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.

    ReplyReply
  91. 23 February 2010Jack says:

    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

    ReplyReply
  92. 23 February 2010Arnold Daniels says:

    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.

    ReplyReply
  93. 18 March 2010David says:

    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

    ReplyReply
  94. 19 March 2010vij says:

    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&quot;;

    /**
    * 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

    ReplyReply
  95. 19 March 2010Sam says:

    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.

    ReplyReply
  96. 23 March 2010dacus says:

    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…

    ReplyReply
  97. 23 March 2010Arnold Daniels says:

    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.

    ReplyReply
  98. 23 March 2010David says:

    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

    ReplyReply
  99. 24 March 2010dacus says:

    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

    ReplyReply
  100. 24 March 2010Arnold Daniels says:

    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.

    ReplyReply
  101. 1 April 2010Sam says:

    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?

    ReplyReply
  102. 4 April 2010Arnold Daniels says:

    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.

    ReplyReply
  103. 7 April 2010Sam says:

    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

    ReplyReply
  104. 9 April 2010Maxime says:

    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.

    ReplyReply
  105. 21 April 2010Arnold Daniels says:

    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.

    ReplyReply
  106. 6 May 2010remo says:

    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.

    ReplyReply
  107. 6 May 2010Arnold Daniels says:

    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.

    ReplyReply
  108. 17 May 2010muswanto says:

    hi arnold, thnx for your sso source code..but i want to connect user name to database(mysql),can you halp me?thnx before..:)

    ReplyReply
  109. 5 June 2010Raju Mazumder says:

    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

    ReplyReply
  110. 3 July 2010Marty says:

    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

    ReplyReply
  111. 4 July 2010Arnold Daniels says:

    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

    ReplyReply
  112. 5 July 2010Marty says:

    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.

    ReplyReply
  113. 6 July 2010Marty says:

    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

    ReplyReply
  114. 6 July 2010Arnold Daniels says:

    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

    php_value session.save_path /var/www/example.com/tmp
    

    In both cases make sure that the path is not accessible for your website visitors.

    ReplyReply
  115. 9 July 2010Stefan says:

    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).

    ReplyReply
  116. 13 July 2010John Adigue says:

    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

    ReplyReply
  117. 13 July 2010Arnold Daniels says:

    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.

    ReplyReply
  118. 22 July 2010Lonjan says:

    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!

    ReplyReply
  119. 27 July 2010Alexander Vassbotn Røyne says:

    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.

    ReplyReply
  120. 27 July 2010Alexander Vassbotn Røyne says:

    Some more info:
    I am not using the jaml thingy, it wouldnt work, so i made a simple login form and ajax script instead.

    ReplyReply
  121. 27 July 2010Alexander Vassbotn Røyne says:

    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..

    ReplyReply
  122. 27 July 2010Arnold Daniels says:

    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.

    ReplyReply
  123. 28 July 2010hucs says:

    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 !

    ReplyReply
  124. 28 July 2010Arnold Daniels says:

    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.

    ReplyReply
  125. 2 August 2010Kacper says:

    Great tip! Thanks!

    ReplyReply
  126. 4 August 2010Silver says:

    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!

    ReplyReply
  127. 4 August 2010Arnold Daniels says:

    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.

    ReplyReply
  128. 5 August 2010Silver says:

    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)

    ReplyReply
  129. 5 August 2010Arnold Daniels says:

    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.

    ReplyReply
  130. 5 August 2010Silver says:

    Thank you very much. Very appreciate your works, and I learned a lot from it. Thanks again. :/

    ReplyReply
  131. 17 August 2010zapatista says:

    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

    ReplyReply
  132. 17 August 2010Arnold Daniels says:

    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

    ReplyReply
  133. 23 August 2010williamjlp says:

    On login page, How can access to $_SESSION['username']?

    ReplyReply
  134. 24 August 2010Arnold Daniels says:

    williamjlp Please read the previous comments. There is no session on the brokers. You need to request the username from the SSO server.

    ReplyReply
  135. 31 August 2010ar_raudy says:

    @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..

    ReplyReply
  136. 1 September 2010Arnold Daniels says:

    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

    ReplyReply
  137. 2 September 2010Katravalli says:

    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

    ReplyReply
  138. 3 September 2010Arnold Daniels says:

    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 :)

    ReplyReply
  139. 3 September 2010Katravalli says:

    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

    ReplyReply
  140. 3 September 2010Arnold Daniels says:

    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).

    ReplyReply
  141. 3 September 2010Katravalli says:

    I didn’t get you Arnold. If you can give an example it may be understandable to my lazy brain. Just i need how would I print username after login… through HTTP request or whatever you say.
    Pls explain with example Arnold
    Regards

    ReplyReply
  142. 3 September 2010Arnold Daniels says:

    Katravalli You can find the example code on github http://github.com/jasny/SSO.

    On line 152 of broker/sso.php you see a function where the broker requests the information of the currently attached user. After the broker has gotten that data, it can print it. An example of this is broker/index.php

       $sso = new SingleSignOn_Broker();
       $user = $sso->getInfo();  // Requests the user info from the SSO server
       if ($user) {
           echo $user->name; // Outputs the name of the user
       } else {
           echo "No user logged in";
       }
    

    This is all the help I can give you. All the information you need is in this article and in the demo software.

    ReplyReply
  143. 3 September 2010Katravalli says:

    Thanks Arnold. Some how, i’m on the track now.
    Regards

    ReplyReply
  144. 4 September 2010ar_raudy says:

    @arnold, I hope you can give me some solution for my thinking.
    this source didnt use LDAP server, right? when I want to use Database server or LDAP server to get some user information I must modify this source. how about you about using LDAP server or database server (like MySQL) for multiple and big applications ?. what i must use from both ?when multiple an big application have their own database, how to integrate them ?

    thanks alot for your answer @arnold :)

    ReplyReply
  145. 5 September 2010Lumpas says:

    Good solution, thanks for sharing.

    ReplyReply
  146. 8 September 2010Arnold Daniels says:

    ar_raudy The SSO server does all the authentication. You can use any method you would normally use there.

    Replace the login, loutout and info functions of server/SSO.php.

    You can find info about php ldap in the manual: http://php.net/manual/en/book.ldap.php

    ReplyReply
  147. 9 September 2010Adrian Pawlik says:

    Thank you Arnold for the library! I’ve noticed that SSO server won’t work if request_order is not set correctly in php.ini. Make sure it contains cookie array (request_order = GP_C_). SSO server class uses $_RESQUEST to get session_id from cookie sent by broker.

    ReplyReply
  148. 14 September 2010ar_raudy says:

    thank you very much @arnold,…
    sorry, what you mean to 307 and 200 in that picture?

    ReplyReply
  149. 14 September 2010Arnold Daniels says:

    ar_raudy Those are HTTP status codes: http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

    ReplyReply
  150. 22 September 2010manoj says:

    i Want to implement this on codeigniter with tank auth

    ReplyReply
  151. 25 September 2010Adrian Pawlik says:

    I found another problem. This solutions works if each website has own domain. When you try to set up 2 applications in the same domain, i.e. example.com/ and example.com/app2/ this will not work becouse the website user enters firstly creates cookie (session_token) and second application will use it while asking SSO for authentication.

    The solution is to set diffrent names for session_token cookie for each broker, for example session_token_brokername.

    In this case it works for the same and for diffrent domains.

    A.P.

    ReplyReply
  152. 27 September 2010Arnold Daniels says:

    Adrian Pawlik The whole reason of using this SSO solution is so you can share session information (like user credentials) across multiple domains. There is no good reason to use this on a single domain (other than testing purposes).

    ReplyReply
  153. 5 October 2010ob1 says:

    Finally !
    Something that works !

    Nice tutorial, you saved many peoples time
    Not even one tutorial, except this one, on the subject of shareing cookies, sessions across multiple domains.

    Good work ^_^

    ReplyReply
  154. 5 October 2010Paul says:

    Hi Arnold,

    Firstly, congratulations on some great coding – I’ve implemented your solution on a range of my blogs and it’s working wonderfully. I’ve done a lot of research into SSO and your solution is by far the most efficient and easy to implement.

    The only downside that I’ve encountered so far is problems with persistence when the browser is closed, reopened, and a new session is started. Logins persist for domains that have been visited with the previous session, but not for domains that haven’t been visited in the previous (logged in) session.

    For example:
    exampleA.com, exampleB.com and exampleC.com are all using your SingleSignOn_Broker class (php, not ajax) to check whether a client is logged in. Assume the sso server is sso.example.com (although I don’t think it’s relevant).

    A client logs in via exampleA.com, then goes to exampleB.com….. the client will still be logged in.

    However, if the client then closes the browser (killing the current session) and reopens it, the client will still be logged in to exampleB.com, but if they go to exampleC.com, they will no longer be logged in. Bear in mind that if the client doesn’t close the browser, then they appear as logged in across A B and C.

    I’ve tried to extend your code to fix this problem but without success. Have you got any ideas? I’d really appreciate it.

    Thanks – Paul.

    ReplyReply
  155. 16 October 2010Buzzknow says:

    Hi Arnold,

    its really great code!!

    i want to try this with CodeIgniter, wish me luck :D

    regards

    ReplyReply
  156. 21 October 2010Chris says:

    Is this code meant to crash when using PHP’s session_start() function. I use a PHP session to maintain persistence of data within my site but when I have the function running it seems to stop the SSO code working, holds it in an infinate lock where no redirects are occuring, it just refuses to load the page, it acts like a super slow connection, but when I remove the session_start() function it works fine. I have tried figuring out why it iss doing this but cant find where in the classes the session_start() function is clashing with other code. Do you have any ideas Arnold?

    ReplyReply
  157. 20 November 2010ob1 says:

    Arnold, I wanted to extend script to keep user logged in for longer period of time, by setting cookie with expire time for one year.
    Are there any drawbacks I could encounter?
    How would you do that?

    Thanks

    ReplyReply
  158. 20 November 2010Arnold Daniels says:

    ob1 That won’t work because the session on the SSO server will already be expired.

    You should solve this, as you would solve it without SSO. Let the SSO server write a cookie with the username + auth hash and check that to automatically log in.

    ReplyReply
  159. 20 November 2010ob1 says:

    Will Do.
    Tnx

    ReplyReply
  160. 26 November 2010chris says:

    Hi Arnold,

    great code.

    One question: Is there any simple possibility to secure the login? The username and the password is hand over in plain text.
    I think one possibility is to secure each broker. But we have arround 50 brokers so that would be a very expensive solution.
    Do you have any idea or advise?

    Thanks in advance,
    chris

    ReplyReply
  161. 29 November 2010Arnold Daniels says:

    chris You could send over an authorization hash instead of the password. This can still be snatched through a man in the middle attack, but by using a timestamp it’s only valid for a few seconds.

    http://www.jasny.net/articles/authentication-without-sessions/

    ReplyReply
  162. 2 December 2010Binit says:

    Thanks Arnold Daniels. I have wasted my three important days, but not get any Script. Finally I have used your script for “Single Sign On”. Its really quite simple & easy to use.

    Thanks again.

    ReplyReply
  163. 3 December 2010andrew says:

    Hi, Arnold

    What’s this error mean “String could not be parsed as XML”. What should i do?

    Thanx,

    ReplyReply
  164. 3 December 2010Kadek says:

    Great..!

    Thanks for the codes :)

    ReplyReply
  165. 17 January 2011guntur says:

    I want single sign-on is using the mysql database.
    is there any script.. help me
    thanks you :)

    ReplyReply
  166. 23 January 2011Скопище ссылок на тему SSO at Electronic Information Technologies says:

    [...] http://www.jasny.net/articles/simple-single-sign-on-for-php/ [...]

  167. 26 January 2011guntur says:

    Warning: SimpleXMLElement::__construct() [function.SimpleXMLElement---construct]: Entity: line 2: parser error : Extra content at the end of the document in C:\xampp\htdocs\ssoprovider\sso.php on line 143

    Warning: SimpleXMLElement::__construct() [function.SimpleXMLElement---construct]: Parse error: syntax error, unexpected ‘”‘ in C:\xampp\htdocs\server\s in C:\xampp\htdocs\ssoprovider\sso.php on line 143

    Warning: SimpleXMLElement::__construct() [function.SimpleXMLElement---construct]: ^ in C:\xampp\htdocs\ssoprovider\sso.php on line 143

    Fatal error: Uncaught exception ‘Exception’ with message ‘String could not be parsed as XML’ in C:\xampp\htdocs\ssoprovider\sso.php:143 Stack trace: #0 C:\xampp\htdocs\ssoprovider\sso.php(143): SimpleXMLElement->__construct(‘?Parse…’) #1 C:\xampp\htdocs\ssoprovider\sso.php(158): SingleSignOn_Broker->parseInfo(‘?Parse…’) #2 C:\xampp\htdocs\ssoprovider\login.php(8): SingleSignOn_Broker->getInfo() #3 {main} thrown in C:\xampp\htdocs\ssoprovider\sso.php on line 143

    ReplyReply

  168. 10 February 2011Lang Nguyen says:

    Dear friend,

    good article but i have prolem

    When i use session in php.ini with memcache

    How to change code support memcahce session in php.ini

    Thank

    ReplyReply
  169. 13 February 2011Arnold Daniels says:

    guntorThe result from the SSO server isn’t valid XML. Probably there is a server error. Output the result from curl and see what is wrong.

    Lang Remove line 168 to 172. Now look at the part where I’m attaching using a file. Replace that with code using memcache.

    On line 78 remove the isset() and replace the file_exists and file_get_contents with memcache.

    ReplyReply
  170. 22 February 2011guntur says:

    I want to change database
    protected static $users = array(
    ‘jan’ => array(‘password’=>”jan1″, ‘fullname’=>”Jan Smit”, ‘email’=>”jan@smit.nl”),
    ‘peter’ => array(‘password’=>”peter1″, ‘fullname’=>”Peter de Vries”, ‘email’=>”peter.r.de-vries@sbs.nl”),
    ‘bart’ => array(‘password’=>”bart1″, ‘fullname’=>”Bart de Graaf”, ‘email’=>”graaf@bnn.info”)
    );

    with database mysql.. is there any script.. help me

    ReplyReply
  171. 24 February 2011Erik Kloeze says:

    Hello Arnold,

    First of all, well coded script! I have read all the comments about the ‘Not attached’ error, but I still cannot seem to figure it out. My client is running Windows Server 2003 and my server is running Linux.

    Symlink is working and also seems to attach. When using fiddler I can see a sequence of requests (sso.php?cmd=attach) from the client to the server, all with a different broker and checksum and all being redirected to the client index.php.

    Error reporting (error_reporting(E_ALL)) is enabled in the server script. The only response I get from the client index.php is:

    Fatal error: Uncaught exception ‘Exception’ with message ‘SSO failure: The server responded with a 406 status: “Not attached”.’ in D:\…\sso\sso.php:162 Stack trace: #0 D:\…\sso\index.php(6): SingleSignOn_Broker->getInfo() #1 {main} thrown in D:\…\sso\sso.php on line 162

    I did have some problems with mod_security in the beginning, but after adding some exceptions, I do not recieve errors from this anymore.

    I have tried pretty much all the suggetions in the above comments. Do you have any idea what I can try to do?

    ReplyReply
  172. 25 February 2011Arnold Daniels says:

    Guntur There is no script I know of Please read comment 87.

    Erik Kloeze Check the symlinks. If they are being created correctly, output the contents of the session files. Is there a variable ‘client_addr’. Also make sure the server writes the error to the (Apache) error log.

    ReplyReply
  173. 27 February 2011Erik Kloeze says:

    The symlink seems to be created, as there is no “Failed to attach; Symlink wasn’t created.” error.

    In sessionStart, ‘User session’ there is a client_addr mentioned, in the ‘Broker session’ after the session_start there isn’t. After the symlink is created, there also is a client_addr in the session file.

    I think that altough there is a symlink, the ‘old’ session simply isn’t picked up? Adding session_name($sid) before the session_start in the ‘Broker session’ also did not work out.

    For the errors, as far as I know, all errors show up in the Plesk Log Files.

    Any ideas left?

    ReplyReply
  174. 28 February 2011Erik Kloeze says:

    Hello Arnold,

    I did some additional debugging, outputting the session_id in the attach function and the sessionstart function.

    When I use the readlink function in the sessionstart function, I get the same session_id as in the attach function. Futhermore, the link variable in the attach function is equal to the session_id in the session_start function (besides the path).

    But it still is not working?

    ReplyReply
  175. 1 March 2011Arnold Daniels says:

    Erik Kloeze Login using SSH and check what is happening.

    ReplyReply
  176. 15 March 2011tomcat says:

    Dude you got a lot of patience answering these questions eh

    ReplyReply
  177. 23 March 2011wawan says:

    Greetings,

    i’ve try ur work but it seems doesn’t work in multiple sub domain?
    what do i have to change if the applicationt are in multiple sub domains?

    Tks

    ReplyReply
  178. 23 March 2011Arnold Daniels says:

    Wawam If it doesn’t work for sub domain, but does work for completely different domains, your session cookie is valid for the whole domain. This is set with the cookie-domain ini directive.

    If you only need to share a session over sub domains and not over different domains, don’t use this SSO solution at all. Simply share the PHP session for the different sites.

    ReplyReply
  179. 23 March 2011wawan says:

    Thanks, for your answer. Very appreciate your works, and I learned a lot from it.

    ReplyReply
  180. 30 March 2011Goose says:

    Have you ever tried this with PHP and .NET. I am looking for a SSO between a PHP website and a .NET website. Can you think of any reasons why this wouldn’t work with both?

    ReplyReply
  181. 31 March 2011Arnold Daniels says:

    Goose No, that should work fine. Set up an SSO server using PHP. You would need to write a broker in .NET. It needs to redirect to the SSO server and than request the data using HTTP, just like the PHP broker.

    ReplyReply
  182. 18 April 2011Ana says:

    Dear Sir,

    Pls help me change code support session store on memcache
    When i change php.ini file use session memcache code error

    I look and research but i dont can change code support memcache
    i read all comment of vistit here but i can not change my code support my memcache

    Pls help me

    Thank verry much

    Ana

    ReplyReply
  183. 24 June 2011Krikil.COM » Blog Archive » Simple Single Sign-On for PHP (Ajax compatible) says:

    [...] Source : Jasny.net [...]

  184. 23 August 2011Luke Barton says:

    For those worrying about SSL certificates for your brokers, perhaps you may consider redirecting the client to the server for authentication, initiating the session on the server then redirecting the client back to the broker?

    ReplyReply
  185. 3 October 2011Charles says:

    Hello everyone,

    Thanks to the developers for this script; I think it’s the answer to my SSO implementation troubles, but I can’t get my head round the installation. Apologies for asking what may appear to others to be quite “basic” questions, I’m no web guru but can get things done once I see the instructions in human-readable language :-)

    I have 2 web sites, already set up and running, both LAMP based with separate but synchronized user databases (same usernames and passwords on both). They are on two separate domains.

    What I have done so far:

    1. Created subdomain for each site: sso.domain1.com and sso.domain2.com.

    2. Uploaded the SSO files to both subdomains, but putting the brokers in the root of each subdomain, along with the index and login files.

    3. Edited each broker sso.php to reference its own server/sso.php e.g. broker sso.php on sso.domain1.com has the entry

    public $url = “http://sso.domain1.com/server/sso.php”;

    4. Fill in the other details.

    5. Go to http://sso.domain1.com in my browser. See a login page, which I fill with credentials in the server sso.php on domain1.com.

    6. Script returns identity, fullname and email, with a logout link.

    7. Now for the really important bit: I go to http://sso.domain2.com, and because I have the same “protected static $brokers” and “protected static $users” data on both server sso.php files, I was not expecting to be asked to log in again.

    8. Script takes me to login page on sso.domain2.com. I don’t log in but when I refresh the browser, I get this fatal error:

    Fatal error: Uncaught exception ‘Exception’ with message ‘SSO failure: The server responded with a 406 status: “Not attached”.’ in /home/bizemail/.weh/sso.php:161 Stack trace: #0 /home/bizemail/.weh/index.php(5): SingleSignOn_Broker->getInfo() #1 {main} thrown in /home/bizemail/.weh/sso.php on line 161

    I know I’m doing something (maybe many things) wrong, and I’d grateful for pointers to properly install the script.

    Regards,

    Charles.

    ReplyReply
  186. 10 October 2011Arnold Daniels says:

    Hi Charles,

    The developers is me :p. So thanks for your praise. Just doing my bit to make the internet world a better place :)

    I looked at what you’re doing. Your creating a multi-master set-up. Where all sites are both server and broker. Though interesting, I think this approach is making the problem complexer than it needs to be.

    Ask yourself the question: Why do I need to have multiple masters?

    Whatever you come up with, you can probably also do with 1 server, even without losing the autonomy. This will make the whole thing much easier ;)

    Let’s take the following: domain1.com is a fully working website. You’ve got your database with your users, an authentication system, etc. Cool…

    Now you’ve got domain2.com which is also a fully working website including database with users, authentication system, etc.

    To share the users across the sites your simply copying them between databases. No magic there… but it works.

    Does this sound about right?

    Now the hard part (which isn’t really that hard). If users login to domain1.com and go to domain2.com you want them automatically to be logged in there as well. That’s what SSO does for you.

    However you want domain1.com as well as domain2.com both handle the authentication by them self and notify the other one. What a pickle :p

    Lets take a slightly different approach. The site on domain1.com stays how it is, but gets the SSO server software as well. The site on domain2.com (and all further domains) get the broker software.

    But you want domain2.com to handle authentication himself you tell me. Ahh, but that’s the easy part. Instead of domain2.com having to set the username and password, just let him send the userid (or username) by modifying function login() on server/sso.php.

    Calling this function will instantly login the user on domain1.com as well.

    Just make sure that only a valid broker can call that method and not some evil hacker.

    Now you only need domain2.com to check at domain1.com is the user is logged in when first visited. Lucky for you, that the broker can already do that :D.

    Told you it was easy.

    ReplyReply
  187. 21 November 2011marios says:

    Dear Sir,

    first of all, i would like to thank you for sharing your code with us.
    I would like to ask you if it is possible to test this at localhost.
    For example, i have a server (folder jasny-SSO/server) and two brokers (Alex: jasny2-SSO/broker and Binck: jasny3-SSO/broker).
    I have connected as jan (username: jan, password: jan1) in the url: http://localhost/jasny2-SSO/broker/index.php and then i tried to connected to the url: http://localhost/jasny3-SSO/broker/index.php when i encountered with the login page.
    What i should do in order to make this work.

    Thank you in advance,

    Marios

    P.S: I comment the line ;session.auto_start = 0 in my php.ini file.

    ReplyReply
  188. 22 November 2011mobile version of the forum? says:

    [...] Canada goose business just as '57 udsalg canada goose . canada goose vest canada goose store canada goose chilliwack bomber canada goose expedition parka canada goose store canada goose montebello parka canada [...]

  189. 23 November 2011marios says:

    Dear Sir,

    once again thank you for your code.
    I am writing again because i do not hear from you since today.
    I would like to ask you if it is possible to test your code at localhost.
    I tried to use two brokers and one server at different folders but it does not work.
    I would appreciate if you help me.

    Thank you in advance,

    Marios

    ReplyReply
  190. 28 November 2011dhtmlextreme says:

    After studying the model here, i created a slightly different version – using the model to run my site – http://www.dhtmlextreme.net
    I just made a blog-post about 2 models – one that runs across subdomains on a website and another version that runs across multiple domains and subdomains or even within the same website.
    I made a plugin for drupal so that the sso can integrate with drupal –
    my server is http://www.accounts.dhtmlextreme.net
    my brokers are http://www.blogs.dhtmlextreme.net, http://www.classrooms.dhtmlextreme.net and others.

    ReplyReply
  191. 29 November 2011butter says:

    Hi Arnold

    I have tried the script, i have to say “wow! its damn great!”
    It work pretty fine in my local and my testing server.
    However, im facing the issue with “406″ stuff, when i place my broker on my local (win7) and sso server on test server (linux). I read every comments above and tried with several fix. yet i cant get it right.

    understand that, this sso suppose to centralise the login auth across domains. im confusing about the _server["REMOTE_ADDR"] as it matching the IP add from local and server IP and final it goes to invalid checksum

    please help and appreciate alots…

    ReplyReply
  192. 30 November 2011butter says:

    Yes! I got the issue solved.

    ReplyReply
  193. 5 December 2011wira says:

    Hi Arnold…
    I want to implement your code using LDAP, which part should I make a change?
    2nd question, I still confuse with ajax-broker implementation, plus your demo site is not working right now, would you active back the demo site so I can learn from it?
    I really appreciate your kindly help

    Thanks for your help…

    ReplyReply
  194. 14 December 2011Gowtham says:

    @Arnold Daniels: Hi Arnold I have the Same problem as Charles. Can you please Explain me wat to modify in server/sso.php as mentioned below

    “But you want domain2.com to handle authentication himself you tell me. Ahh, but that’s the easy part. Instead of domain2.com having to set the username and password, just let him send the userid (or username) by modifying function login() on server/sso.php .”

    ReplyReply
  195. 14 January 2012Arnold Daniels says:

    Hi all, the demo’s are currently broken indeed. I need to look at that soon. Also I’ve decided to create a full featured lib from this example, since I’m still getting a lot of response years after writing this article.

    Sorry @Gowtham I didn’t reply to you earlier. Since the broker will do the authentication, it can simply send the userid to the SSO server instead of the username/password.

    ReplyReply
  196. 16 January 2012Sir Đoàn says:

    Thank you so much for this toturial ^^

    ReplyReply
  197. 25 January 2012Gougousis Alexandros says:

    Hi! Nice code!
    I have used it to create an SSO-based application using the Yii Framework. It’s cool!
    I would like to ask you one thing. What is the reason of “attaching” to the SSO-Server?
    Why not direclty sending the un-logged client to the SSO-Server for logging?

    Anyway,thanks for sharing the code!

    ReplyReply
  198. 8 February 2012Sunil Singh says:

    Hi Arnold, great tutorial, but I still unable to find how to achieve this on a PHP CMS, as I am developing two social networking site having different concept using Boonex Dolphin CMS of php. But the client wants single sign-on on both site. just like, gmail, googleplus, orkut.
    So how to achive this … if you can help me out by clearly mentioning it step by step, then it will be very easy for me to understand.

    Thanks n Regards
    Sunil Singh

    ReplyReply
  199. 15 February 2012gps says:

    Thanks for great tutorial. I’m looking for a SSO solution for my websites but with no luck. As your mention, I will try in a different approach. Thanks again!

    ReplyReply
  200. 6 March 2012ST says:

    I’ve been using your SSO solution for about 6 months now. Some of our customers do have problems to login due to cookie restrictions. They use an open wireless network which you can find in hotels or other public locations. It seems that there are specific cookie restrictions which does not allow to share the cookie information from server to broker.

    Does anybody else have problems with that?

    ReplyReply
  201. 3 April 2012elier says:

    hi, sorry i speak a little english

    which are the required configuration for the sso server ?

    i put it in a server with php 5.1 and it work good

    i put it in a server with php 5.3 and it does not work

    the session configuration in php.ini is the same in both servers, any other parameter is required ?

    i have 3 clients and when the domain of sso server is the server with php 5.1 clients work good, but when i put in the client configuration the domain of sso server with php 5.3 it does not work.

    thanks and sorry for my english

    ReplyReply
  202. 3 April 2012elier says:

    hi again, i have found the problem is with symbolic link, in the server with php 5.3, the sso server script does not create the symbolic link, someone know why does happen ?

    thanks.

    ReplyReply
  203. 4 April 2012Gisela Maja says:

    Hi guys,

    i have 2 online systems; joomla cms and xtcommerce shop and i am looking for sso for both system.

    my goal is: i want to login into joomla and after on clicking on shop i want to login through sso into shop

    also is there is a need, if user changes password on joomla, also password should be changed automatically in shop system.

    so my question, what is to do, that i can implement your script to make a sso for my systems.

    can you please provide me with more informations how to do!!

    cheers

    gisela maja

    ReplyReply
  204. 6 April 2012flamencoman says:

    @elier:
    I had that problem and resolved it by creating directory with ‘Apache user’, by allowing to all to write to that directory and pointed session_save_path to that directory.

    ReplyReply
  205. 6 April 2012flamencoman says:

    Hi Arnold,
    I’ve implemented your SSO code and after one smaller fix it worked.
    This part created a problem for me:
    if (isset($_SESSION['client_addr']) && $_SESSION['client_addr'] != $_SERVER['REMOTE_ADDR']) {session_regenerate_id(true);}

    Scenario:
    I logg in via broker_1.
    When broker redirects (with 307) first time to the SSO server, server puts in $_SESSION client’s remote addres and redirects to broker’s login page after which “info()” method is called where broker checks via cURL if user is logged in.
    Problem is that when broker asks SSO server via “info()”, SSO server sees broker’s $_SERVER['REMOTE_ADDR'] and sets it in $_SESSION and that triggers session_regenerate_id(true);

    Changes I’ve implemented:
    Broker SSO: serverCmd -> added “client’s_remote address” as POST variable
    Server SSO: sessionStart -> instead of asking if (isset($_SESSION['client_addr']) && $_SESSION['client_addr'] != $_SERVER['REMOTE_ADDR']) {
    ask
    if (isset($_SESSION['client_addr']) && $_SESSION['client_addr'] != $_REQUEST['remote_address']) {

    I’m using PHP 5.3

    What’s more interesting, “symbolic link” problem (that elier mentioned) exists when brokers are at the same server.
    Code with

    ReplyReply
  206. 12 April 2012Gisela Maja says:

    @flamencoman or others

    can you please briefly help me how to testablish a single sign on between my 2 web-systems ( Joomla and XT-Commerce) so that there is only one login possible.

    what is to do to make this issue happen??

    note: you can also send me how-to description to: maja340@gmail.com

    cheers

    Gisela Maja

    ReplyReply
  207. 18 April 2012Mikesch says:

    Good job!
    I did the SSO login with this script and everything works fine regarding the login.
    I also need to store information in my own session variables, if I put some information into session variables at the login and call for example at the main view the session variable, they are no more accessible.
    So how to tell a script so use the initialized session from SSO during login?

    Thx in advance!

    ReplyReply
  208. 15 May 2012Thomas says:

    I just released a PHP-based SSO server/client solution and would like feedback:

    http://barebonescms.com/documentation/sso/

    This article did make me go “hmm” in a couple spots. You say that there are many SSO solutions out there, yet my research turned up basically nothing – and still turns up nothing that even compares to what I’ve built. You’ve got OpenID, OAuth 1 and 2, and not much else. The landscape is pretty barren. And if you want to offer the user multiple sign in options at the server level, it gets even more sparse (HybridAuth and my solution are pretty much it).

    You do address AJAX in this article but you are proxying requests to a server. Anyone can build a proxy and, as you pointed out, you have to trust the servers that proxy the requests. I don’t know how I feel about that, especially if you want to support mobile devices – you might want to consider the possibility that the application was poorly designed in the first place. The SSO solution I’ve built saves the request ($_GET, $_POST, etc.), redirects to the server, the server manages the login process, and then the request is restored when the server redirects back to the client. So you could author a comment or forum post and, once you completed the entire sign up and/or sign in process, the comment/forum post would finish posting as if you had been logged in the entire time.

    ReplyReply
  209. 15 May 2012witi says:

    Hello ppl,

    First of all, thx for that library that is very powerful ! We are using the Ajax implementation on our network and just finished to install it.
    After several days of test / bug / debug, we notice that broker name SHOULD NOT contains ‘-’ because of

    preg_match('/^SSO-(\w*+)-(\w*+)-([a-z0-9]*+)$/', $_REQUEST[session_name()], $matches)

    In server’s sessionStart() function.

    Just in case, if some of you are trying to use it with a broker name like xxxxx-xxxxx ;)

    Cheers

    ReplyReply
  210. 15 May 2012Arnold Daniels says:

    @Thomas: Cool that you’ve implemented an SSO solution. I’ve just browsed through it, so far it looks pretty good.

    You’ve got a number of solutions based on SAML like http://simplesamlphp.org and a whole number of things in Java. There definitively space for easier and better libs though.

    It depends on your use case. If you choose to redirect the client to the SSO server, you can easily choose to have the user login directly instead of through the broker. However, you can also just load an image from the SSO server and proxy the authentication, so the client does not have to leave the page. You can choose which of the 2 ways you prefer, other SSO implementations (including yours) don’t give you that option :(.

    ReplyReply
  211. 15 May 2012Arnold Daniels says:

    @flamencoman: Forgot to say thanks… Thanks :)

    ReplyReply
  212. 4 June 2012Robert says:

    @flamencoman: hmm how can i added “client’s_remote address”? im amateur in SSO

    ReplyReply
  213. 15 June 2012Umesh Kulkarni says:

    Hi Arnold Daniels,

    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

    These demo links are not working.
    Can you please let me know which links should I use to see the demo?

    Thanks,
    Umesh Kulkarni

    ReplyReply
  214. 14 July 2012Jmatt says:

    @ Witi

    Untested, but this might work.


    preg_match('/^SSO\-(\w*+)\-(\w*+)\-([a\-z0-9]*+)$/', $_REQUEST[session_name()], $matches)

    ReplyReply
  215. 18 October 2012Bill says:

    I’m wondering if this is still working and what php applications are working. Any further development or better solutions available now? I’d like to integrate Drupal, Magento and WordPress into a SSO solution but I realize all the synching, updating, ect that would have to occur between the different “application architectures for customer roles (username, password, ect)”… Just wondering if anyone’s trying to do anything like that out there…

    I have a partial working solutions for wordpress/mage but syncing customers and password updates not so much..

    ReplyReply
  216. 22 October 2012Arnold Daniels says:

    @Bill. The demo’s aren’t working anymore. I should really fix them. This is basically just a proof of concept and far from a solid lib. I planned to create a lib, but it’s unlikely I’ll get around to it soon.

    ReplyReply
  217. 30 January 2013Whoops says:

    the demo links no longer seem to be working….?

    ReplyReply
  218. 15 February 2013Arnold Daniels says:

    @Whoops I’ll fix it soon.

    ReplyReply
  219. 29 April 2013Jeet Chaudhari says:

    Really Thank You…!

    I was struggling from many days to implement SSO system for my website and my other websites which are in development. I tried many things but did not get success.

    I even tried installing barebones sso, but it was too complicated with so many tables in database, as I already have all website’s user database and session database developed, with their classes.

    This is the place where I found exactly what I was searching for, an easy code to understand and modify. I implemented it on my website, But I am getting one small problem.

    When I visit the page which just checks if user is logged or not, (On this page I do not want to force user to login, so removed redirect) It returns 406 error, which says invalid checksum (The generate attach checksum returns null). If I refresh same page again I was visiting, then it works.

    If you can tell me, why 1st time it gets invalid checksum when user isn’t logged in, I would be really thankful. to avoid this, should I just put redirect statement, instead of header 406? Or I did something wrong in checking if user is logged in?

    This is the code I used to check if person is online or not.

    function isLoginValid () {
    $sso = new SingleSignOn_Broker();
    $user = $sso->getInfo();

    if (!$user) {
    return false;
    } else {
    return true;
    }

    ReplyReply
  220. 26 May 2013Kyle says:

    I tried going to the github to download the SSO you wrote but cannot find it on there….did you remove this? Is there still a way to get it?

    ReplyReply
  221. 28 May 2013Arnold Daniels says:

    @Kyle: GitHub changed the download section. I’ve fixed the link.

    ReplyReply
  222. 1 June 2013David Baker says:

    We are looking to implement an SSO piece from a PHP marketing site to our ASP.NET enterprise portal.
    In other words, a user would be on a PHP marketing page, be able to put in their username and password in the appropriate fields and be redirected, authenticated (or not) against our other site user database.
    Is this something you could assist / consult with us on? Fee?
    Thanks in advance –
    David

    ReplyReply
  223. 3 July 2013nhymxu says:

    Some user manager system have two part: client site and server site, work with API (return json, xml, …)

    Why you need three part: client, ajax, server?

    I don’t know about this?
    sorry because my english not well.

    Can you talk about this?

    Thanks you

    ReplyReply
  224. 15 July 2013OSS says:

    Hello Arnold

    Thanks for this article and its nice code

    i wonder if i can use your code in two different virtual hosts : the first one is the broker and the second one will be the server side.

    Thanks and good continuation .

    ReplyReply
  225. 2 October 2013conglin.deng says:

    hi,

    i have a website want to use this php login framework, but encounter a problem, that any page need login, so i change the sso.php below line code. just refer U. make the sessionToken not change.

    56 $this->sessionToken = ’476bdd2c2e296936a91a411dfefdb38c’;

    53 public function __construct($auto_attach=true)
    54 {
    55 #if (isset($_COOKIE['session_token'])) $this->sessionToken = $_COOKIE['session_token'];
    56 $this->sessionToken = ’476bdd2c2e296936a91a411dfefdb38c’;
    57
    58 if ($auto_attach && !isset($this->sessionToken)) {
    59 header(“Location: ” . $this->getAttachUrl() . “&redirect=”. urlencode(“http://{$_SERVER["SERVER_NAME"]}{ $_SERVER["REQUEST_URI"]}”), true, 307);
    60 exit;
    61 }
    62 }

    ReplyReply
  226. 2 October 2013conglin.deng says:

    @conglin.deng:

    just ignore what i say,sorry, the method have problem。

    ReplyReply
  227. 15 November 2013udaya says:

    Hi,

    I have three different PHP web application and planning to implement SSO for these. Could you please explain how to integrate your code to make it working. Thanks in advance.

    ReplyReply
  228. 11 April 2014Wahid says:

    Hi Arnold,

    I’m teaching the SSO and I’m so interest your article about the SSO.

    My questions are:
    1. How to implement the SSO using the user existing in database?
    I am changing the code on server\sso.php like below, but it is still not work.
    protected static $users = “select * from user”;

    2. How to implement on 2 (two) different domains?

    Any idea for me. Thank you so much.

    ReplyReply
  229. 12 April 2014Romain says:

    Hi Arnold.
    Thank you very much for the download, it seem to be exactly what I need.
    But I have the same problem of remo:


    remo said:
    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.

    But I don’t understand your answer :


    Arnold said:
    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.

    Where can I check if the session file is created?
    I don’t understand what can I do to fixe the problem. I hope you can help me.
    Thanks

    ReplyReply
  230. 13 April 2014Arnold Daniels says:

    @Romain: Check your session directory. The directory is configured in php.ini by session.save_path. (Probably /tmp or /var/lib/php5 under linux).

    ReplyReply
  231. 6 August 2014Simple Single Sign-On for PHP | Nguyễn Tiến Công says:

    […] source: http://www.jasny.net/articles/simple-single-sign-on-for-php/ […]

  232. 7 August 2014sign in using ajax says:

    […] Simple Single Sign-On for PHP (Ajax compatible) – Jasny … […]

  233. 18 September 2014can you make money minecraft Server says:

    Hurrah! Finally I got a webpage from where I can genuinely get useful facts regarding my study and knowledge.

    ReplyReply
  234. 26 September 2014Willa says:

    Otrohet erbjuder dig spänning som Ԁu länge har missat.
    Upptäck njutningen av att se din partner іn action,alltså knulla med någon annan, ɗu komme finna diig själv få deen ultimata kicken av erotisk njutning när ɗu ѕеr din partner blii nullad av еn främling.

    Bara tanken av att träffa еn total främling för еn het knullträff på ett kanske sliskigt hotellrum borde få vilken kille som
    helst att få ståkuk.

    ReplyReply
  235. 29 September 2014garage door opener Ventura says:

    Hello it’s me, I am also visiting this website on a regular basis, this
    web page is in fact fastidious and the people are really sharing nice thoughts.

    ReplyReply
  236. 29 September 2014imgur.com says:

    Hi all, here every one is sharing these kinds of experience, so it’s
    pleasant to read this weblog, and I used to pay a visit this webpage all the time.

    ReplyReply
  237. 1 October 2014dating norge says:

    Jeg liker ikke kvinner som ikke vet hva ɗe vil men trenger damer som еr tent på Sex
    og haar lyst til å prøve ut nye ting. Det ƙan også hende
    at det renner noe ut (særlig om ԁu har sprutet sæd inn) når dս tar pikken ut igjen. Lɑ penis trykke mօt åpningen en god stund, oog når ɗen soom
    skal penetrere еr klar trekker vedkommende
    pusten dypt inn og puster ut igjen; ”schwupp” så
    metter penis innafor.

    ReplyReply
  238. 11 October 2014candy crush cheats level 658 says:

    Hi there everyone, it’s my fiest visit at this site,
    and paragraph is truly fruitful in favor of me, keep up posting these types of content.

    ReplyReply
  239. 20 October 2014budi says:

    Thanks for this

    ReplyReply

Write a comment: