views:

349

answers:

3

Hi

I have multiple asp.net sites. When a user logs unto one of the sites, I want to store a cookie telling me that a user has logged on. When the user later visits one of the other sites I have, I would like to read the cookie from that site.

AFAIK you neither can read cookies from or write cookies to other sites, so what could a workaround be? Perhaps making a redirect to http://www.othersite.com/SaveCookie.aspx ?

Give me some ideas :-)

+1  A: 

You're looking for a Single Sign-On (SSO) solution.

Tomas Lycken
No I don't think so, because you can only log on to one of the sites. The cookie I want to read from the other sites, only contain info that the user at some time has been logged on to the "main"site.
Karsten
A: 

If it's possible for you to host your sites at different subdomains below the same domain, you can save cookies that are shared for the whole domain, e.g.:

"site1.yourdomain.com" and "site2.yourdomain.com"

can both read cookies saved to the domain "yourdomain.com"

Another alternative is to tell the other site about the login via a request to it, as in your redirect suggestion. You could do this in several ways, e.g. by loading the page in an iframe, sending the data directly from one server to another, and so on. None of these are particularly elegant, though, and in the case of login, as Tomas Lycken says, you should really be going for a proper SSO implementation.

Jonas H
+2  A: 

One of our clients has exactly the same requirement (logging into multiple sites on different domains), complicated by the fact that one of the sites requires that the user is logged in to a classic ASP application, a .NET 1.1 application and a .NET 3.5 application running on different hardware, but under the same domain...

We've basically implemented a system of round-robin style redirects, where each domain logs the user in, then bounces them on to the next domain until they return to the original domain at which point they are redirected to their original request.

So (pages and domains changed to protect the innocent):

  1. User requests www.example1.com/page1.aspx
  2. A cookie is set that tells us the user was attempting to access page1.aspx, and the user is sent to the www.example1.com/login.aspx
  3. The user logs in, and is then redirected to www.example2.com/processlogin.aspx?token=EncryptedToken
  4. ProcessLogin.aspx checks for a cookie telling it where to direct the user, if it can't find one, it decrypts the token, logs the user in on example2.com, and then redirects them to www.example1.com/processlogin.aspx?token=EncryptedToken (or example3.com - repeat as required)
  5. As in 4, ProcessLogin.aspx checks for the cookie, finds it, deletes it and redirects the user to /page1.aspx.

If the user later on visits a page on www.example2.com, before the authentication ticket timeout, they will still be logged in on that site as well.


Edit to respond to comment

That depends on how you are making the "request to the other pages". If you make the request from your code behind, what you're doing is effectively setting the cookie on the server, rather than on the users browser.

Cookies need to be issued by the server to the client browser, and that is done in the headers of the page response - so you need to direct the users browser to a page on the other site to issue the cookie from that domain.

You could generate a request to the other page in an IFrame, or try and do it in a self closing pop-up window - but that has other issues like pop-up blockers, flickering windows, etc.

After some investigation we found that a round-robin set of redirects like this was the simplest and most reliable solution.

A very basic code setup:

An .aspx page, containing a Login control, with a method "OnLoggedIn" attached to the LoggedIn event of the control:

void OnLoggedIn(object sender, EventArgs e){
  string returnUrl = Request.QueryString["returnUrl"];

  // Create new cookie, store value, and add to cookie collection
  HttpCookie myCookie = new HttpCookie("WhereTo");
  myCookie["ReturnUrl"] = ReturnUrl;
  Response.Cookies.Add(myCookie);

  // Redirect user to roundtrip login processor on next domain.
  // Work out domain as required.
  string redirect = GetNextDomain();
  // Add encoded user token
  redirect += "?token=" + EncodeUserToken();

  // Redirect the user, and end further processing on this thread
  Response.Redirect(redirect, true);
}

Then on both servers you have ProcessLogin.aspx, that has something like this in it:

protected void Page_Load(object sender, EventArgs e){
  // Look for redirect cookie
  if (Request.Cookies["WhereTo"]["ReturnUrl"] != null){
    // Save value from cookie
    string redirect = Request.Cookies["WhereTo"]["ReturnUrl"];

    // Delete original cookie by creating an empty one, and setting it
    // to expire yesterday, and add it to the response.
    HttpCookie myCookie = new HttpCookie("WhereTo");
    myCookie.Expires = DateTime.Now.AddDays(-1d);
    Response.Cookies.Add(myCookie);

    // Redirect the user, and stop processing
    Response.Redirect(redirect, true);
  }

  // Still here, so log in and redirect
  string encryptedToken = Request.QueryString["token"];

  if (!string.IsNullOrEmpty(encryptedToken)){
    // Decrypt token, and log user in
    // This will vary depending on your authentication mechanism
    PerformLogin(encryptedToken);
  }

  // Redirect user to roundtrip login processor on next domain.
  // Work out domain as required.
  string redirect = GetNextDomain();
  // Add encoded user token - no need to recalculate, it will be the same
  redirect += "?token=" + encryptedToken;

  // Redirect the user, and end further processing on this thread
  Response.Redirect(redirect, true);
}
Zhaph - Ben Duguid
That sounds like what I was thinking. You seem to be making redirects, I'm thinking for my case, couldn't I just make a request to the other pages? As I'm kind of new to ASP.net, could you show me how this code would look like?
Karsten
Nice, thanks a lot :-)
Karsten