Jay and I recently worked through a problem at work that I want to share here since I thought it was a pretty good solution. I certainly found nothing that was as clean as this. So here goes.
The problem is we want to have a single web site that will house all of the login controls, such as simple login, NTLM login, change password, password recovery. We decided to use the new asp.net controls that came with Visual Studio 2005 which are apart of the .NET framework 2.0. They were well architected by using a provider pattern. Have to give Microsoft kudos for that. So lets name this site http://www.login.com/ for simplicity. We'll eventually convert it to SSL for added security. We have several websites in different domains that will need to go to this site to login. Let's call two of them, http://www.sitea.com/ and http://www.siteb.com/. What we'd like is for each of these sites to have a cookie that would contain a guid that is of course unique to the user and is also stored in a security database field. We will assign a timeout period on this guid, which we'll call a "token". When the user navigates to sitea.com we try to read the cookie. If exists and we make a database call to see if the token has expired. If it hasn't then the user is good to go, they are authenticated and have certain rights. If they don't then we provide a login link on the page. They click the login link which navigates them to a "stopover" page called "security.aspx". Here is where we create a cookie that sets the "calling url", or the originating page. From security.aspx we call Response.Redirect to login.com and add on a query string "?call=A". More on the query string later. We get to login.com and present the user with the standard login form. We read the query string "call" which tells us who called us. "A" means that sitea.com called us and we look up what web page on sitea.com we need to redirect to when the user successfully gets logged in. User logs in successfully, "A" means we need to redirect to http://www.sitea.com/security.aspx. We attached the newly created guid as a query string. At security.aspx we read the "calling url" cookie to find out what page we need to get back to. We write the token cookie based on the query string and then simply redirect to our "calling url". Voila you are back to your starting page with a valid token.
Other solutions I've read don't involve a "stopover" site.
They bundle up the calling url in the query string. That to me is
messy, especially if your url is long and full of query string data.
Now I know there is some insecure stuff going on here, like exposing the guid token in a clear text query string. But this isn't a financial site and were not dealing with a site that hackers would really bother with. It's secure enough for our purposes. If it becomes a problem we could start logging ip addresses that uses the token and expire it if we find two different ips are using it. Possibly lock out the user if it persists.
Our solution doesn't solve the Single Sign On problem either. Possibly
we could write a cookie at login.com that gets read and automatically
redirects back to the calling url. That would assume that the cookie
belongs to the logged in user. There are a couple of inititiaves out
there that are trying to solve this in an open manner (as opposed to
the closed Microsoft Passport system). One I know is called OpenID.