Single sign-on with Forms Authentication

(Note: Updates after first post are in red - Dec 2004)

Every now and then I see people asking for some way to achieve single sign-on using Forms Authentication so you may reuse the Forms ticket with along several sites. It happens that you can have this functionality (not provided out of the box) with just a few tweaks.

Downloads

You can download the code sample for the SSO Forms Authentication from here.  The example code is provided as source code that you can use "as is" or customize it for your own applications.

SSO Sample

The sample that you can download form the above link, has two sites. The one named “FormsAuth2” is the entry point site that will call the login page located on the “FormsAuth” site. After the authentication process, the Forms ticket will be reused from the first site “FormsAuth2” with all the user name and roles info inside it. After diving into the details, let me say that these two sites are structured in two areas (public and private) in order to clearly differentiate between the publicly accessible areas and restricted areas that require authenticated access andSecure Sockets Layer (SSL). I use separate subfolders beneath the virtual root folder of both applications to hold restricted pages such as the login form and other sample form with checkout links and the like, that needs to be secured by using HTTPS. By doing so, I can use HTTPS for specific pages without incurring the SSL performance overhead across the entire site.

Configuration

The configuration showed on the following figure is a sample of how you can set the Forms Authentication attributes with security in mind. You should follow these hints for SSO Forms Auth. First of all, you should have the same settings (see forms element attributes) that are listed below on every site that you want to adhere to SSO.·         Name·         Protection·         PathThe machineKey element might be configured on the machine.config file or on every web.config application file. In the first scenario, you may have the encryption key set to something like this (this is the default setting, albeit useless for this scenario):
<machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey= "AutoGenerate,IsolateApps" validation="SHA1"/> 
 

The "IsolateApps" means that a different key will be AutoGenerated for *each* application. You can either remove the isolateApps option (for apps on the same machine) or insert a specific key value for it to use (for apps on different boxes). This last option is the one that is used on following the config sample.

 

<configuration>

<system.web>

   <authentication mode="Forms">

      <forms loginUrl="Secure\login.aspx" protection="All" requireSSL="true" timeout="10" name="FormsAuthCookie" path="/FormsAuth" slidingExpiration="true" />

      </authentication>     <!-- The virtual directory root folder contains general pages.          Unauthenticated users can view them and they do not need           to be secured with SSL. -->      <authorization>        <allow users="*" /> <!-- Allow all users -->   

      </authorization>

      <machineKey validationKey="C50B…CABE" decryptionKey= "8A9BE8FD67AF6979E7D20198CFEA50DD3D3799C77AF2B72F" validation="SHA1"/>   </system.web>   <!-- The restricted folder is for authenticated and SSL access only.        All pages on the Secure subfolder will be under SSL access. --> 

<location path="Secure" >

   <system.web>

      <authorization>

        <deny users="?" />

      </authorization>

   </system.web>

</location>

</configuration> 
 Note: Check ouy the path attribute. This should be aligned with the app name. If you want to have SSO on every app, just leave the default value "/".

Principal Creation

After gathering the user credentials you will perform the authentication process and after that you will retrieve the user roles if you want to use the .NET role authorization pattern. This implies the creation of an Identity and a Principal object that will contain this data. So on the login page server side and after the auth process you will get the Forms ticket and save there your roles info and may be any other user profile related data (beware of size constrains, less than 4KB). 
// Do auth with your preferred auth method  WindowsIdentity identity = WinAccessHelper.LogonUser( UserId, Password );   // Add roles  string[] roles = WinAccessHelper.Roles( new WindowsPrincipal( identity ) );                    HttpCookie cookie = FormsAuthentication.GetAuthCookie( UserId.Text, false );  FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);   // Store roles inside the Forms cookie.  FormsAuthenticationTicket newticket = new FormsAuthenticationTicket(                                                              ticket.Version,                                                               ticket.Name,                                                                  ticket.IssueDate,                                                             ticket.Expiration,                                                            ticket.IsPersistent,                                                          String.Join( "|", roles),                                                      ticket.CookiePath);                                                                                                    cookie.Value = FormsAuthentication.Encrypt(newticket);  Context.Response.Cookies.Set(cookie);  Response.Redirect( FormsAuthentication.GetRedirectUrl( newticket.Name, newticket.IsPersistent ) );                  // For different domains, should use the cookie domain//HttpCookie formsCookie = FormsAuthentication.GetAuthCookie( UserId.Text, false );//formsCookie.Domain = "localhost.com";//Response.AppendCookie( formsCookie );//Response.Redirect( FormsAuthentication.GetRedirectUrl( UserId.Text, false ) );//FormsAuthentication.RedirectFromLoginPage( UserId.Text, false ); 
 

Principal Retrieving

On each AuthenticateRequest event of every SSO “federated” site you may retrieve your saved user info and create your Principal object and load them onto the User object of the current HttpContext instance. This is accomplished on the following figure. 
 protected void Application_AuthenticateRequest(Object sender, EventArgs e){     

   if (Context.Request.IsAuthenticated)

   {            // retrieve user's identity from httpcontext user              

     FormsIdentity ident = (FormsIdentity)Context.User.Identity;

     // retrieve roles from the authentication ticket userdata field            

     string[] arrRoles = ident.Ticket.UserData.Split(new char[] {'|'});                 // create principal and attach to user                Context.User = new System.Security.Principal.GenericPrincipal(ident, arrRoles);      }} 
 

Multiple Domain Scenarios

For Domain wide authentication scenarios, you can set domain-wide cookie only for second level domain, or for third level domain if second level domain contains three or less characters. It means that you cannot set cookie for domain "com" or "co.uk", but can for "example.com" or "example.co.uk". You can find a good example of this here.Hopefully this sample will give you a good idea of how to implement a SSO scenario with Forms Authentication. Enjoy it! This posting is provided "AS IS" with no warranties, and confers no rights. 
Published Wednesday, June 09, 2004 5:59 PM by HernanDL

Comments

# re: Single sign-on with Forms Authentication

Wednesday, June 09, 2004 4:08 PM by Paul Wilson
Looks intriguing -- I'll be bookmarking this.

# re: Single sign-on with Forms Authentication

Wednesday, June 09, 2004 6:06 PM by Joe
What I'd really like to see is a sample of SSO between an ASP and an ASP.NET application. This would help with phased migration of legacy apps from ASP to ASP.NET.

As far as I see it could be done if the ASP app had methods to encrypt and decrypt the authentication cookie - i.e. if there were a version of the FormsAuthentication.Decrypt / Encrypt methods callable from ASP (e.g. a COM object).

# re: Single sign-on with Forms Authentication

Wednesday, June 09, 2004 6:27 PM by Hernan
That’s an interesting mix. As far as I know, that approach should work fine. Just be sure that you have the same machineKey settings in machine.config file of your ASP server as the one you have on your ASP.NET server. Tell me if you ever try this and whether you where successful or not.

Thanks,
Hernan.

# re: Single sign-on with Forms Authentication

Thursday, June 10, 2004 8:07 AM by Andrey Skvortsov
Thanks,wonderful post!

# re: Single sign-on with Forms Authentication

Thursday, June 10, 2004 10:38 PM by Joe
I agree it's an interesting mix, I'm surprised I haven't found a ready-made solution.
Unfortunately I haven't found an elegant solution for it yet.

I have a crude solution where the ASP.NET FormsAuthentication login page redirects to a login page in the ASP app, which then stores the authentication info in a cookie using a custom encryption algorithm. My ASP.NET app checks this cookie and updates it's sliding expiration, replicating the same custom encryption algorithm.

Ideally I'd like to use the ASP.NET login page and cookie in both ASP and ASP.NET apps. But I still haven't figured out a way to decrypt/encrypt the ASP.NET FormsAuthentication cookie from within the ASP app.

# re: Single sign-on with Forms Authentication

Friday, June 11, 2004 7:31 PM by Hernan
I'm thinking to incluide an example of this topic on my next security talk scheduled for mid august. When I finish these samples I will post them here.

Regards,
Hernan.

PD: Unfortunately I'm not able to have a solution earlier than that because of my currently overloaded bandwidth. ;-)

# re: Single sign-on with Forms Authentication

Saturday, June 12, 2004 12:23 AM by Daniel Cazzulino
A much awaited post from you buddy!
You go a little fast for non-Einsteins, but it's OK ;)

# SSO Forms Authentication

Tuesday, June 15, 2004 12:24 PM by TrackBack

# re: Single sign-on with Forms Authentication

Thursday, February 01, 2007 1:19 PM by teddytgy

Hi,

I tried to download SSO_FormsAuth.zip but the link is not working any more could you please send me the file @ teddytgy@gmail.com or post other alternative where I can download the zip file.  Thanks,

Teddy

# re: Single sign-on with Forms Authentication

Thursday, May 17, 2007 6:45 AM by asdfs

asdf

# re: Single sign-on with Forms Authentication

Tuesday, July 17, 2007 6:58 AM by venkatesh

Hi,

I am trying to create users in the active directory using my web application. I am using the following line of code

string domain = "LDAP://" + DomainName;

DirectoryEntry DEntry = new DirectoryEntry(domain);

// wants to check if exists.

/// 1. Create user account

DirectoryEntries Users = DEntry.Children;

DirectoryEntry NewUser = Users.Add("CN=" + UserName, "user");

/// 2. Set properties

SetProperty(NewUser, "givenname", UserName);

SetProperty(NewUser, "SAMAccountName", UserName);

SetProperty(NewUser, "userPrincipalName", UserName);

//SetProperty(NewUser, "mail", email);

NewUser.CommitChanges();

The problem I am facing is , I am not able to create any particular user under the "User" folder under the active directory. It is getting created directly under the domain heirarchy. I want them to be under the user folder.

Could you please tell me what's wrong with my code and how to rectify it?

Thanks

# re: Single sign-on with Forms Authentication

Sunday, December 09, 2007 1:24 AM by kimsea

I see your posted is good. But your link is not working. Please help me about Signle Sign On with Multi Virtual Directory.

Thank you,

# re: Single sign-on with Forms Authentication

Monday, February 04, 2008 9:40 AM by Vanessa Romero

Great post. Now, I have a question and maybe you can help me.... I have a set of asp.net websites running under the same domain that I already made the SSO work between them. The problem is that I need to add our exchance server webmail and our share point portal. At this point I have no clue on how to do that. We are using Active directory and people from outside the network need to have access. Any help will be appretiated.

# re: Single sign-on with Forms Authentication

Friday, February 08, 2008 5:57 AM by Samit

SamitSamit,Samit,Samit,SamitSamitSamit,Samit,Samit,Samit,v,v,Samit,Samit,Samit

# re: Single sign-on with Forms Authentication

Sunday, April 27, 2008 11:13 AM by feechka-ei

<a href= http://index1.srepon.com >suffolk england</a> <a href= http://index3.srepon.com >pulmonary ventricular defect</a> <a href= http://index2.srepon.com >blood gang</a> <a href= http://index4.srepon.com >what to do when when adult children hate mother</a>

# re: Single sign-on with Forms Authentication

Friday, December 26, 2008 5:08 AM by Albina-gq

<a href= membres.lycos.fr/maffals >genetic disorters</a>

# re: Single sign-on with Forms Authentication

Friday, December 26, 2008 5:23 AM by ellaela-yv

<a href= membres.lycos.fr/dertull >zx10r graphics</a>

# Forms Authentication for multiple applications | keyongtech

Wednesday, January 21, 2009 10:26 PM by Forms Authentication for multiple applications | keyongtech

Pingback from  Forms Authentication for multiple applications | keyongtech

# re: Single sign-on with Forms Authentication

Thursday, April 02, 2009 6:20 AM by Prepare UK Test

Thanks for sharing this article...

http://www.prepareuktest.co.uk

# re: Single sign-on with Forms Authentication

Saturday, May 16, 2009 2:21 AM by phytoplankton imposed output

business references found north result

# re: Single sign-on with Forms Authentication

Wednesday, June 17, 2009 4:06 AM by real estate agent

Thanks for sharing.

# re: Single sign-on with Forms Authentication

Thursday, June 25, 2009 12:05 AM by Ajit

Will this SSO implementation work in a web farm enviorment?

Leave a Comment

(required) 
(required) 
(optional)
(required)