Have you ever come across a situation where you want to have multiple login pages with Forms Authentication.  Forms Authentication directly supports one login page, but there is a workaround. Today we will see how to achieve this.

For an example, let’s say you want two login pages where one is for administrators and other is for customers.

image
Default.aspx

When the user clicks on Admin, he should be redirected to administrator content where the user will have to authenticate himself as an administrator. When the user clicks on Customer, he will be redirected to customer content again where the user will have to authenticate himself as a customer. Administrators login page will have some different content and customers login page will have some other.
 
image
Admin Login Page

image
Customer Login Page

Here is a web application with two folders inside the project. One is for Administrators and the other is for Customers. Let's create a login page and a sample page inside Admin folder and create another login page and a sample page inside Customer folder. Here is what we have after completing previous steps.

image
Folders inside Solution Explorer

For demonstration purposes in the admin login page, there is a drop-down where we can select which type of credentials to us to try in admin login. If Login with Admin Credentials is selected we should be able to see admin content. If I Login with Customer Credentials is selected, we should be prompted to admin login again.

image
Admin Login Page

In the admin login button click event is the following code.
protected void Button1_Click(object sender, EventArgs e)
{
string userData = "";
string userName = "";

if (DropDownList1.SelectedIndex == 0) // admin
{
userData = "Admin"; // set userData
userName = "Admin User Name";
}
else if (DropDownList1.SelectedIndex == 1) //customer
{
userData = "Customer"; // set userData
userName = "Customer User Name";
}

// initialize FormsAuthentication
FormsAuthentication.Initialize();

// create a new ticket used for authentication
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(15), false, userData);

// encrypt the cookie using the machine key for secure transport
string encTicket = FormsAuthentication.Encrypt(authTicket);

// create and add the cookies to the list for outgoing response
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);

Response.Cookies.Add(faCookie);

Response.Redirect("/Admin/WebForm1.aspx");
}
Next we modify the global.asax file by adding the “Application_AuthenticateRequest” event.
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)
{
//HttpCookie cookie = HttpContext.Current.Request.Cookies["UserRole"];
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;

// get the stored user-data, in this case it's our users' role information
string userData = ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.Current.User = new GenericPrincipal(id, roles);
}
}
}
}
Modify the “web.config” file as follows.
<authentication mode="Forms">
   <forms name="LoginCookie" loginUrl="Login.aspx" protection="None" path="/" defaultUrl="Login.aspx" timeout="30" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
Now secure the directories role-based Forms Authentication. For that we are modifying the “web.config” file as follows.
<!--for admin folder allow users having the role 'Admin' and deny other-->
<location path="Admin" allowOverride="true">
<system.web>
<authorization>
<allow roles="Admin" />
<deny users="*"/>
</authorization>
</system.web>
</location>

<!--for content folder allow all-->
<location path="Content" allowOverride="true">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>

<!--for scripts folder allow all-->
<location path="Scripts" allowOverride="true">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>

<!--for images folder allow all-->
<location path="Images" allowOverride="true">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>

<!--for login.aspx allow all-->
<location path="Login.aspx" allowOverride="true">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>

<!--for default.aspx allow all-->
<location path="Default.aspx" allowOverride="true">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>

<!--for Admin/Login.aspx allow all-->
<location path="Admin/Login.aspx" allowOverride="true">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>

<!--for Customer/Login.aspx allow all-->
<location path="Customer/Login.aspx" allowOverride="true">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
As you saw above, loginUrl in the forms element can be only one. So we have created a page inside root called “Login” and am not interested in the design of that page. Just in the Page_Load event and the following code. In here is when the main login page is loading it will identify the request type (admin or customer) by analysing the URL and redirect to the relevant login page.
protected void Page_Load(object sender, EventArgs e)
{
char[] character = { '/' };

if (Request["ReturnUrl"] != null)
{
// Request["ReturnUrl"].ToString() ->
// http://localhost:1965/Admin/Login.aspx;
// http://localhost:1965/Customer/Login.aspx

string[] strs = Request["ReturnUrl"].Split(character);

// if the second part is Admin go to admin login
if (strs[1] == "Admin")
{
Response.Redirect(@"/Admin/Login.aspx");
}
// if the second part is Customer go to customer login
else if (strs[1] == "Customer")
{
Response.Redirect(@"/Customer/Login.aspx");
}
}
}
Now we are all set. In the Default.aspx, we have two hyperlinks for admin content and customer content.
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Admin/WebForm1.aspx">Admin</asp:HyperLink>
<br />
<asp:HyperLink ID="HyperLink2" runat="server" NavigateUrl="~/Customer/WebForm1.aspx">Customer</asp:HyperLink>
In the admin login when logged in with admin credentials we can see the admin content. If logged in with customer credentials we will be redirected to admin login page again.

image
Admin Can View Admin Content

image
Customer Can't View Admin Content

We will not show you how to do this for the customer’s login page. The concept is the same. You can download the sample project from MSDN Code Gallery and try this out.
Download Sample

Hope this helps.

Happy Coding.