Thread: ASP.NET/Single Sign-On for everyone

Single Sign-On for everyone

blogs.neudesic.com/blogs/michael_morozov/archive/2006/03/17/72.aspx

-- 11/05/2009 20:27:24: post edited by sergey.





Re: Single Sign-On for everyone

 5. SSO for two applications in different domains.


We’ve been quite successful creating shared authentication cookies so far, but what if Foo and Bar are in different domains – http://foo.com and http://bar.com? They cannot possibly share a cookie or create a second cookie for each other. In this case each site will need to create its own cookies, and call the other site to verify if the user is logged in elsewhere. One way to do it is via a series of redirects.

In order to achieve that, we will create a special page (we’ll call it sso.aspx) on both web sites. The purpose of this page is to check if the cookie exists in its domain and return the logged in user name, so that the other application can create a similar cookie in its own domain. This is the sso.aspx from Bar.com:

<%@ Page Language="C#" %>

<script language="C#" runat="server">

void Page_Load()

{

   // this is our caller, we will need to redirect back to it eventually

   
UriBuilder uri = new UriBuilder(Request.UrlReferrer);

   HttpCookie c = HttpContext.Current.Request.Cookies[".BarAuth"];

   if (c != null && c.HasKeys) // the cookie exists!

   {

      try

      
{

         string cookie = HttpContext.Current.Server.UrlDecode(c.Value);

         FormsAuthenticationTicket fat = FormsAuthentication.Decrypt(cookie);         

         uri.Query = uri.Query + "&ssoauth=" + fat.Name; // add logged-in user name to the query

      
}

      catch

      
{

      }

   }

   Response.Redirect(uri.ToString()); // redirect back to the caller

}

</script>

This page always redirects back to the caller. If the authentication cookie exists on Bar.com, it is decrypted and the user name is passed back in the query string parameter ssoauth.

On the other end (Foo.com), we need to insert some code into the http request processing pipeline. It can be in Application_BeginRequest event or in a custom HttpHandler or HttpModule. The idea is to intercept all page requests to Foo.com as early as possible to verify if authentication cookie exists:

1. If authentication cookie exists on Foo.com, continue processing the request. User is logged in on Foo.com

2. If authentication cookie doesn’t exist, redirect to Bar.com/sso.aspx.

3. If the current request is the redirect back from Bar.com/sso.aspx, analyse the ssoauth parameter and create an authentication cookie if necessary.

It looks pretty simple, but we have to watch out for infinite loops:

// see if the user is logged in

HttpCookie c = HttpContext.Current.Request.Cookies[".FooAuth"];

if (c != null && c.HasKeys) // the cookie exists!

{

   try

   
{

      string cookie = HttpContext.Current.Server.UrlDecode(c.Value);

      FormsAuthenticationTicket fat = FormsAuthentication.Decrypt(cookie);

      return; // cookie decrypts successfully, continue processing the page

   
}

   catch

   
{

   }

}

// the authentication cookie doesn't exist - ask Bar.com if the user is logged in there

UriBuilder uri = new UriBuilder(Request.UrlReferrer);

if (uri.Host != "bar.com" || uri.Path != "/sso.aspx") // prevent infinite loop

{

   Response.Redirect(http://bar.com/sso.aspx);

}

else

{

   // we are here because the request we are processing is actually a response from bar.com

   if (Request.QueryString["ssoauth"] == null)

   {

      // Bar.com also didn't have the authentication cookie

      
return; // continue normally, this user is not logged-in 

   
} else

   
{

      // user is logged in to Bar.com and we got his name!

      
string userName = (string)Request.QueryString["ssoauth"];

   

      // let's create a cookie with the same name

      
FormsAuthenticationTicket fat = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddYears(1), true, "");

      HttpCookie cookie = new HttpCookie(".FooAuth");

      cookie.Value = FormsAuthentication.Encrypt(fat);

      cookie.Expires = fat.Expiration;

      HttpContext.Current.Response.Cookies.Add(cookie);

   }

}

The same code should be placed on both sites, just make sure you are using correct cookie names (.FooAuth vs. .BarAuth) on each site. Since the cookie is not actually shared, the applications can have different <machineKey> elements. It is not necessary to synchronize the encryption and validation keys.

Some of us may cringe at the security implications of passing the user name in the query string. A couple of things can be done to protect it. First of all we are checking the referrer and we will not accept the ssoauth parameter from any source other then bar.com/sso.aspx (or foo.com/ssp.aspx). Secondly, the name can easily be encrypted with a shared key. If Foo and Bar are using different authentication mechanisms, additional user information (e.g. e-mail address) can be passed along similarly.

 

-- 11/05/2009 20:45:19: post edited by sergey.





Re: Single Sign-On for everyone

www.codeproject.com/KB/web-security/CrossDomainAuthentication.aspx





Re: Single Sign-On for everyone

SAML


www.sourceid.org/projects/saml_1_1_dotnet_toolkit.cfm





Re: Single Sign-On for everyone

.NET Sql Authorization Manager


sourceforge.net/projects/netsqlazman/





Re: Single Sign-On for everyone

Архитектура информационной системы


www.gotdotnet.ru/forums/13/91180/433224/#post433224


Some information to think about... But not a solution.





Re: Single Sign-On for everyone

Some articles (Rus):


Declarative and Imperative Security в .Net web сервисах


stump-workshop.blogspot.com/2007/01/declarative-and-imperative-security-net.html


 


Designing Application-Managed Authorization (MSDN)

msdn.microsoft.com/en-us/library/ee817656.aspx


ASP.NET delegation and impersonation (Rus)


stump-workshop.blogspot.com/2006/12/aspnet.html





Re: Single Sign-On for everyone

Single Sign-on in ASP.NET and Other Platforms


www.codeproject.com/KB/aspnet/SingleSignon.aspx





Re: Single Sign-On for everyone

Cross Site Authentication and Data Transfer


aspalliance.com/1513_Cross_Site_Authentication_and_Data_Transfer.all





Re: Single Sign-On for everyone

OpenID: Another Approach to Identities Single Sign-On, But Decentralized and Open


www.b-eye-network.com/view/6405


A Recipe for OpenID-Enabling Your Site


www.plaxo.com/api/openid_recipe