Sometimes you have requirement to maintain single forms authentication for several applications on same web server or different web server or on different domain. Here we discuss about single forms authentication for two applications on single web server.
Before going to in-depth, I will explain about forms authentication for single application.
For Forms authentication, you have to change authentication mode to “Forms” in web.config file, specify login page (which does not require authentication) and specify role for authorization as shown below.
<configuration>
............
<system.web>
<authentication mode="Forms">
<forms name="MYWEBAPP.ASPXAUTH" loginUrl="Login.aspx" protection="All" path="/" />
</authentication>
<authorization>
<deny users="?" />
<allow roles="user"/>
</authorization>
</system.web>
</configuration>
Authenticate the request in Application_AuthenticateRequest event of Global.asax file as shown below.
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (HttpContext.Current.User != null)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if (HttpContext.Current.User.Identity is FormsIdentity)
{
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
// Get the stored user-data, in this case, our roles
string userData = ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(id, roles);
}
}
}
}
Here you are getting user role ticket UserData and assigning the role to cookie.
Now create login form and check for correct user name and password. If both are valid allow the user to view other pages in web application as shwon below. Here we are hard coded the user name and password as abc and 123456.
protected void btnLogin_Click(Object sender, EventArgs e)
{
try
{
bool userAuth = (txtUsername.Text.Trim() == "abc") && (txtPassword.Text.Trim() == "123456");
if (userAuth)
{
// Create a new ticket used for authentication
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, // Ticket version
txtUsername.Text.Trim(), // Username associated with ticket
DateTime.Now, // Date/time issued
DateTime.Now.AddMinutes(30), // Date/time to expire
false, // "true" for a persistent user cookie, "false" for a Non persistent user cookie
"user" , // User-data, in this case the roles
FormsAuthentication.FormsCookiePath);// Path cookie valid for
// Encrypt the cookie using the machine key for secure transport
string hash = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(
FormsAuthentication.FormsCookieName, // Name of auth cookie
hash // Hashed ticket
);
// Set the cookie's expiration time to the tickets expiration time
if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;
// Add the cookie to the list for outgoing response
Response.Cookies.Add(cookie);
Response.Redirect("Default.aspx");
}
else
{
lblError.Text = "Username / password incorrect. Please try again.";
lblError.Visible = true;
}
}
catch (Exception ex)
{
}
}
After user entering the correct credentials, create cookie and hard code the role as “user”(which was mentioned in web.config file). For successful authentication and authorization we are navigating the user to Default.aspx page.
Now we discuss about same forms authentication for multiple web applications on same web server. Generally whenever you are creating the cookie for one web application, it will not work for other application if you are not adding proper settings.
For that create another application FormsAuthenticationApp2 with same pages and same authentication settings as we have in FormsAuthenticationApp1 web application.
Run first application, Loign with user name(abc) and password(123456). Then browse Default.aspx of second web application(FormsAuthenticationApp2), you are redirected to Login.aspx page of second web application(FormsAuthenticationApp2). This because of you are not maintaining the same authentication for two web applications(FormsAuthenticationApp1 and FormsAuthenticationApp2).
To maintain the same authentication for web two applications add machine key for web.config file of two applications as shown below.
<system.web>
<machineKey decryption="Auto" validation="SHA1" decryptionKey="AutoGenerate" validationKey="AutoGenerate" />
........
</system.web>
In the above, decryption attribute specifies the algorithm used to encrypt and decrypt the forms authentication cookie and the validation attribute specifies the hash or encryption algorithm used when an authentication cookie is signed.
Possible values for decryption attribute are Auto, AES (the government standard encryption algorithm), and 3DES (Triple DES). By default, the decryption attribute is set to Auto, which causes the ASP.NET Framework to select the encryption algorithm based on the capabilities of the web server. Possible values for validation attribute are AES, MD5, SHA1, and TripleDES.
The decryptionKey attribute represents the key used to encrypt and decrypt the authentication cookie. The validationKey represents the key used when the authentication cookie is signed. By default, both attributes are set to the value AutoGenerate, which causes the ASP.NET Framework to generate a random key and store it in the LSA (LSA means your web server Local Security Authority).
Now login to FormsAuthenticationApp1 application and try to browse Default.aspx of FormsAuthenticationApp2. Great, you are able to browse the Default.aspx of FormsAuthenticationApp2 without login to the FormsAuthenticationApp2. Here you are maintaining the FormsAuthenticationApp1 web application authentication for FormsAuthenticationApp2 web application also.
For our comfort, we added the FormsAuthenticationApp2 web application Default.aspx url in the FormsAuthenticationApp1 web application Default.aspx and vice versa as shown below.
FormsAuthenticationApp1 Default.aspx
<form id="form1" runat="server">
<div>
Login was successful for Web Application - 1<br />
For second web application <a href="http://localhost:1576/FormAuthenticationApp2/Default.aspx">Click here</a>
</div>
</form>
In my system, FormAuthenticationApp2 web application Default.aspx url is http://localhost:1576/FormAuthenticationApp2/Default.aspx.
FormsAuthenticationApp2 Default.aspx
<form id="form1" runat="server">
<div>
Login was successful for Web Application - 2<br />
For first web application <a href="http://localhost:1373/FormAuthenticationApp1/Default.aspx">Click here</a>
</div>
</form>
In my system, FormsAuthenticationApp1 web application Default.aspx url is http://localhost:1373/FormAuthenticationApp1/Default.aspx.
In my next article, I will discuss about how to handle Forms Authentication for multiple applications on multiple server (like on web farm).