Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a Shared Login Service across Multiple Domains?

I'm interested in how to implement a shared cross-domain login system as well as best practices and security precautions to take. If you are familiar with 37Signals, you are probably accustomed to their usage of having a shared universal authentication mechanism whereby you do not have to subsequently login if you use the top level navigation to a different product. I would like to implement something in a similar fashion.

The closest thing I've found online is the Wikipedia entry on a Central Authentication Service and the response to Cross Domain Login - How to login a user automatically when transfered from one domain to another, which may be slightly different in this case.

I have inspected their session cookies to get a grasp on what they're doing in the process. Initially, each product link has a "goto" uristub, i.e.:

https://MY_COMPANY.campfirenow.com/id/users/[int_identifier]/goto

Using FireCookie and the NET tab in Firebug, I'm able to see the cookies that are set and the redirects that occur in the process. The goto url fires a 302 redirect to:

https://MY_COMPANY.basecamphq.com/login/authenticate?sig=[BASE64_ENCODED_AND_ENCRYPTED_DATA]

The session identifier is recreated, most likely for CSRF purposes. Some of the data in the cookies as well as the GET parameter sig were partially decrypted using base64_decode to the following:

// sig GET param array(2) {   [0]=> ���ף�:@marshal_with_utc_coercionT7�z��<k��kW"   [1]=>   string(18) "���k�<kn8�f���to��" }  // _basecamp_session cookie session param string(247) { :_csrf_token"1Sj5D6jCwJKIxkZ6oroy7o/mYUqr4R5Ca34cOPNigqkw=:session_id"%060c0804a5d06dafd1c5b3349815d863" flashIC:'ActionController::Flash::FlashHash{: @used{: auth{"               MY_COMPANY{:                        user_idi�3 :identity_idi�W����������s�]��:�N[��: 

߾�����"

The encoding is breaking the code block. Thanks for your help!

like image 211
Corey Ballou Avatar asked Nov 29 '10 18:11

Corey Ballou


People also ask

How does SSO work across domains?

The SSO domain authenticates the credentials, validates the user, and generates a token. The user is sent back to the original site, and the embedded token acts as proof that they've been authenticated. This grants them access to associated apps and sites that share the central SSO domain.

What is multi domain SSO?

About multi-domain support for SSO Access Policy Manager (APM) provides a method to enable users to use a single login or session across multiple virtual servers in separate domains.

Can a user be part of multiple domains?

An organizational unit can include users from different domains. For example, you might have a Marketing unit containing users from two domains. Learn more about organizational units and limitations with multiple domains.

What is cross domain authentication?

Cross-domain authentication is a common approach in identity management that authenticates users for sites that run on different domains. ReachFive handles this even for browsers that block third-party cookies. Cross-domain authentication is much more streamlined when using SSO.


2 Answers

I think the key in your Q is where you write "whereby you do not have to subsequently login if you use the top level navigation to a different product".

I will explain: You want to be able to move from site1.com to site2.com and let site2.com know that you are some user that logged in via site1.com.

because cookies are not shareable between different domains (other than subdomains but I guess you are not talking about sub-domains) you have to pass some information on the link to site2.com that will let it talk with its back-end and know what user you are.

lets start with a naive solution and then work our way to make resolve some of the problems that it poses: suppose you have a users table on some back-end DB and your user has some ID. now assume that the user authenticated on site1.com and he is user 123 from your DB. The most naive solution would be to call site2.com/url/whatever?myRealID=123 and have site2 check for this ID and "belive" the user that this is indeed him.

Problem: Anyone (even a valid user of your site) that will see your link can create a link with myRealID=123 or try other values for it. and site2.com will accept him as that user.

Solution: lets not use guessable ID's suppose you add to your users table a unique GUID and if user 123 has a guid of 8dc70780-15e5-11e0-ac64-0800200c9a66 then call site2.com/url/whatever?myGuid=8dc70780-15e5-11e0-ac64-0800200c9a66.

New Problem: well even though It would be very unlikely that someone will guess your user's GUID his GUID can still be hijacked by some middle man that sees this link and it someone will get the guid he can use it for ever.

Solution: Use a private key saved on your server to sign a string that contains the following data items, current time-stamp, destination site (i.e "site2.com") the said GUID, this signature can be translated into saying "This is a proof that this link was created by the site at the said time for the user that has this GUID to authenticated by this domain" and send it to site2.com along with the time-stamp and GUID. Now when site2.com gets the link he can make sure that it is signed properly and if some middleman or originally user would try to change it in any way (either by modifying the time or GUID) then the signature would not match and site2.com will refuse authenticating the user.

One last problem: if the link is intercepted by a middleman he can still use if from some other machine.

Solution: add a nonce to the passed parameters. The nonce is just a random number that your authentication system should make sure that it does not allow you to authenticate with this number more then once (hence then name N(umber)-ONCE). Note that this means that each link you create on site1.com that leads to site2.com should have a distinct nonce which needs to be saved on the back-end for later validation.

because you don't want to keep adding records to this nonce table forever it is custom to decide that such a link is only valid for some given time after its creation. and so you can create nonce records that are older than this time limit.

I hope that this is the outline you where looking for. It is possible that I missed something but those are the basic guidelines, use a signature to prove the authenticity of the data in the link and use a nonce to prevent middleman attacks. I would also recommend using HTTPS for those links if possible.

Eyal

like image 68
epeleg Avatar answered Sep 29 '22 12:09

epeleg


You could try to implement a Global Network Auto-Login solution à la Stack Overflow.
There's an insightful post regarding its brilliant implementation by Kevin Montrose here.

It would require Cookies, HTML5 localStorage, Javascript, Iframe and a lot of security checks but I think it's worth it.

like image 22
systempuntoout Avatar answered Sep 29 '22 10:09

systempuntoout