home | articles | site map | contacts
about us
consulting
client login
support
contacts



  Redirect a Login By Role in C# ASP .NET
Primary Objects C# .NET RSS Feed More C# ASP .NET
Articles by Primary Objects
enter email address
 

Introduction

Redirecting a user after login to a C# ASP .NET web application is a common feature found in most web applications. It's also quite common to have multiple types of users logging into the ASP .NET web application, differing by the type of role membership they belong to, and each requiring a redirect to their specific landing page. While this can certainly be achieved with a couple of Response.Redirect() calls, you can create a much more robust automatic redirect-by-role solution.

This article describes how to automatically redirect users upon login, based upon their role membership. Since the list of redirect URLs may change frequently, we'll store them conveniently within the web.config configuration file. New user roles and redirect URLs can be added without recompilation of the C# ASP .NET web application.

 
Redirect Login Role C# ASP .NET

On First Thought, It Isn't Pretty

When thinking about redirecting users after login, based upon their role, the first way of implementing this is to create a couple of if/then and Response.Redirect statements, as follows:

        protected void btnLogin_Click(object sender, EventArgs e)
        {
            //
            // Validate user, check login, create authentication ticket, populate roles, etc.
            // ...
            //

            if (Roles.IsUserInRole(txtUsername.Text, "User"))
            {
                Response.Redirect("~/User/Default.aspx");
            }
           else if (Roles.IsUserInRole(txtUsername.Text, "Administrator"))
           {
                Response.Redirect("~/Admin/Default.aspx");
           }
        }

However, what happens when we need to add another login redirect to the system for a new role type? We would have to edit the if/then block, add a new conditional, and re-compile the web application. Eventually, this can create a mess. Consider the following:

        protected void btnLogin_Click(object sender, EventArgs e)
        {
            //
            // Validate user, check login, create authentication ticket, populate roles, etc.
            // ...
            //

           if (Roles.IsUserInRole(txtUsername.Text, "User"))
           {
                Response.Redirect("~/User/Default.aspx");
           }
          else if (Roles.IsUserInRole(txtUsername.Text, "Administrator"))
          {
               Response.Redirect("~/Admin/Default.aspx");
          }
          else if (Roles.IsUserInRole(txtUsername.Text, "Tester"))
          {
              Response.Redirect("~/Tester/Default.aspx");
          }
         else if (Roles.IsUserInRole(txtUsername.Text, "Customer"))
         {
             Response.Redirect("~/Customer/Default.aspx");
         }
        else if (Roles.IsUserInRole(txtUsername.Text, "Client"))
        {
             Response.Redirect("~/Client/Default.aspx");
        }
        else if (Roles.IsUserInRole(txtUsername.Text, "Manager"))
        {
            Response.Redirect("~/Cave/Default.aspx");
        }
        // ...
     }

As you can tell, the list isn't looking pretty. We can actually break this down into a much more clean system by pulling out the decision logic in the if/then statements and moving it to the web.config, where we can quickly and easily change it, without re-compiling or changing code.

Defining the Redirect URLs in the Web.Config

We'll start off by defining the list of URLs that our users will be redirected to, based upon their role membership. The URLs will be listed in the web.config, for easy modification at a later time. This decouples the list of URLs from the web application source code and allows us to quickly add new roles and login redirects on the fly. The web.config redirect login block appears as follows:

<?xml version="1.0"?>
<configuration>
  <loginRedirectByRole>
    <roleRedirects>
      <add role="Administrator" url="~/Admin/Default.aspx" />
      <add role="User" url="~/User/Default.aspx" />
    </roleRedirects>
  </loginRedirectByRole>
</configuration>

Notice in the above web.config section, we've defined a custom section block named loginRedirectByRole. This block holds a list of roleRedirects. The roleRedirects list functions in the same way as adding connection strings to your web.config. In this manner, it should be extrememly easy to add and remove roles and login redirects.

Each item added to the roleRedirects list consists of a role name and a URL. In the example above, we've defined two roles: Administrator and User, which automatically redirect to their own landing page after login. It's important to note that the redirected pages exist in their own sub-folders, separated by role. This is important so that you can create separate web.config files to restrict security to those folders by role. For example, the ~/User/ folder contains the following web.config file:

<?xml version="1.0"?>
<configuration>
  <appSettings/>
  <connectionStrings/>
  <system.web>
    <authorization>
      <allow roles="User" />
      <deny users="*" />
    </authorization>
  </system.web>
</configuration>

Only users who contain the role User will be allowed to access this folder. Similarly, the ~/Admin/ folder contains the following web.config file:

<?xml version="1.0"?>
<configuration>
  <appSettings/>
  <connectionStrings/>
  <system.web>
    <authorization>
      <allow roles="Administrator" />
      <deny users="*" />
    </authorization>
  </system.web>
</configuration>

Only users who contain the role Administrator will be allowed to access this folder. You could easily expand the roleRedirects list as requried, depending on the different user roles your ASP .NET web application may contain.

Since we've created a custom configuration section in the main web.config, we'll also need to define the configuration section tag in the configSections area of your main web.config as follows:

 <configSections>
    <section name="loginRedirectByRole" type="WebApplication1.LoginRedirectByRoleSection" allowLocation="true" allowDefinition="Everywhere" />
 </configSections>

The changes we've made to the project's main web.config file, thus far, would appear as follows:

<?xml version="1.0"?>
<configuration>
   <configSections>
       <section name="loginRedirectByRole" type="WebApplication1.LoginRedirectByRoleSection" allowLocation="true" allowDefinition="Everywhere" />
    </configSections>

  <loginRedirectByRole>
    <roleRedirects>
      <add role="Administrator" url="~/Admin/Default.aspx" />
      <add role="User" url="~/User/Default.aspx" />
    </roleRedirects>
  </loginRedirectByRole>

  <appSettings>
  </appSettings>
  <connectionStrings>
  </connectionStrings>

  <!-- rest of web.config ... -->

</configuration>

We've now defined the web.config structure for holding the login redirect URLs. Next, we can move on to creating the code to handle it.

Reading the Login Redirect List with a Custom ConfigurationSection

With the web.config custom configuration section defined, we now need to create a custom configuration section reader class to obtain the list of login redirects and provide easy access. We can do this by creating the following class:

    public class LoginRedirectByRoleSection : ConfigurationSection
    {
        [ConfigurationProperty("roleRedirects")]
        public RoleRedirectCollection RoleRedirects
        {
            get
            {
                return (RoleRedirectCollection)this["roleRedirects"];
            }
            set
            {
                this["roleRedirects"] = value;
            }
        }
    }

    public class RoleRedirectCollection : ConfigurationElementCollection
    {
        public RoleRedirect this[int index]
        {
            get
            {
                return (RoleRedirect)BaseGet(index);
            }
        }

        public RoleRedirect this[object key]
        {
            get
            {
                return (RoleRedirect)BaseGet(key);
            }
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new RoleRedirect();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((RoleRedirect)element).Role;
        }
    }

    public class RoleRedirect : ConfigurationElement
    {
        [ConfigurationProperty("role", IsRequired = true)]
        public string Role
        {
            get
            {
                return (string)this["role"];
            }
            set
            {
                this["role"] = value;
            }
        }

        [ConfigurationProperty("url", IsRequired = true)]
        public string Url
        {
            get
            {
                return (string)this["url"];
            }
            set
            {
                this["url"] = value;
            }
        }
    }

Note the above code is a standard definition of a web.config custom configuration section. The structure follows that defined in the web.config. With this class defined, we'll be able to access the roleRedirects list by calling myConfigSection.RoleRedirects.

The Key to Redirecting Logins by Role

We've completed the web.config declarations and have created the custom configuration section to read it. We can now create the actual method which determines the redirect page based upon the logged in user's role.

        /// <summary>
        /// Redirect the user to a specific URL, as specified in the web.config, depending on their role.
        /// If a user belongs to multiple roles, the first matching role in the web.config is used.
        /// Prioritize the role list by listing higher-level roles at the top.
        /// </summary>
        /// <param name="username">Username to check the roles for</param>
        private void RedirectLogin(string username)
        {
            LoginRedirectByRoleSection roleRedirectSection = (LoginRedirectByRoleSection)ConfigurationManager.GetSection("loginRedirectByRole");
            foreach (RoleRedirect roleRedirect in roleRedirectSection.RoleRedirects)
            {
                if (Roles.IsUserInRole(username, roleRedirect.Role))
                {
                    Response.Redirect(roleRedirect.Url);
                }
            }
        }

The above code simply instantiates the custom configuration section to obtain the list of login redirect URLs. It then compares the currently logged-in user's role to those listed in the web.config. When it locates a matching role, it redirects the user to the designated landing page. If a user happens to belong to more than one role, the user will be redirected to the first matching role's landing page. In this manner, you can list higher priority roles at the top of the web.config list. For example, an Admin user can belong to the User role and the Administrator role, so that he can access both areas of the application. Since his role is listed first in the web.config, he'll be redirected to the ~/Admin/Default.aspx page, which is probably the expected landing page, even though he is also a member of the User role (which redirects to ~/User/Default.aspx).

Where to Call the Redirect Method Depends on What You're Using

We've now completed the framework for automatically redirecting users, upon login, based upon their role. However, we still need to add the code which calls our RedirectLogin method. The location of this call depends on the type of login mechanism that you're using.

The most common method of logging a user in is by using the standard ASP .NET Login control. When using the Login control, you'll have a control tag as follows:

    <asp:Login ID="ctlLogin" runat="server" RememberMeSet="True" DestinationPageUrl="~/User/Default.aspx" onloggedin="ctlLogin_LoggedIn">

Notice in the above code, we add a handler for the OnLoggedIn event. This allows us to know when the user has completed logging into the web application so that we can automatically redirect him to the proper landing page, as follows:

        protected void ctlLogin_LoggedIn(object sender, EventArgs e)
        {
            RedirectLogin(ctlLogin.UserName);
        }

If you're using your own login control you can utilize the same redirect function call, but placed within the area after you validate and create the authentication ticket cookie.

        protected void btnLogin_Click(object sender, EventArgs e)
        {
            //
            // Validate user, check login, create authentication ticket, populate roles, etc.
            // ...
            //

            RedirectLogin(txtUsername.Text);
        }

In either case, after the user has been successfully logged in, and his roles have been populated, you can call the RedirectLogin() function, as shown above, to begin the redirect.

If you are using the standard ASP .NET Login control, you will need to also define a Membership Provider and a Role Provider, as found in this article.

Download complete project source code for this article.

 

Conclusion

Redirecting users, upon login, based on their role can be as simple as adding a few if/then statements and a Response.Redirect call. However, by decoupling the decision logic from your C# ASP .NET web application code and moving it into the web.config, you can help create a much more efficient, robust, and extensible system. By separating user landing pages by sub-folder and restricting permissions by role, we can safely designate landing pages by role membership and help achieve a more seamless experience for the user.

About the Author

This article was written by Kory Becker, founder and chief developer of Primary Objects, a software and web application development company. You can contact Primary Objects regarding your software development needs at http://www.primaryobjects.com

  Post comment >
        
DateUserComment
11/12/2008Dave U can make it even more simple:
if (Roles.IsUserInRole(loginControl.UserName, "Admin"))
            {
                  loginControl.DestinationPageUrl = "~/Admin/Default.aspx";
            }

greetz


12/31/2008Fernando Hi Guys,

Could you please make available the whole Project so that I can identify where to write those C# code. My e-mail is femachado@gmail.com. Thanks a lot.


2/18/2009kcrewjap can you also make available the whoe Project to me as well? my email is kcrewjap@hotmail.com

Thanks


3/17/2009luolong This is a great article, but I'm having trouble implementing it.  
Can you post the entire project, or e-mail it to me?

My e-mail address is luolong@yahoo.com.

Thanks!

Luo Long


3/19/2009sanya I kind of like it, but ca not implement it, can you please send the project to my email toplinktech@yahoo.com

I will appreciate this.

Thanks.


3/20/2009Sean Great!   It works well! Thanks

4/6/2009kaliya Hi please email me this whole project
My email Id is kmkpeurmal@gmail.com

With Regards
Kaliyaperumal.M


4/13/2009Mashai Hi Guys,

Could you please make available the whole Project so that I can identify where to write those C# code in the web.config file. My e-mail is arcktosh@gmail.com.

Kind Regards.


5/23/2009Sajid loginRedirectByRole tag is giving error of UNRECOGAMIZED ELEMENT
so how can it work error free?


5/23/2009K Sajid,

loginRedirectByRole is a custom configuration section in the web.config. You need to add the configSection tag to your web.config for loginRedirectByRole and specify the DLL that defines the tag. See the part in the article above under the paragraph "Defining the Redirect URLs in the Web.Config".


5/23/2009Ehsan I am Facing some problem in Implementing this. This is Really very
great. Can   you Please Email the Whole Project. So i can See where
i am missing something.
Here is my Email e_a_farooqi@hotmail.com


5/24/2009Ehsan i have followed the tuturial line by line but i am getting error in web.confiq
file unable to locate the schema for url and add.
Please help how to resolve this
thanks


5/24/2009K I've added a link to download the full project source code.
You can download the project here:
http://www.primaryobjects.com/temp/RedirectLoginByRole.zip


5/25/2009Ehsan Thankyou so much

6/2/2009aymen jemli First of all i thank you for these wonderful lines of code.
I've followed your example step by step
of course i used the source code to verify the imports (using) and
finally i made it.
Dave we all know the method you proposed but plz verify the conclusion of the article.
thank you.
www.aymen.ca.cx


6/22/2009Julia Very nice work, thanks for posting this.

9/2/2009Kay Does this code work in Visual Web Developer 2005 Expree Edition?

12/9/2009Rais Hi Guys,

could you please tell me how tu use it with an sql server data base
cause i don't know how to add new user like with the createuserwizard control?
my @
m_rais@hotmail.com

Thanks


Profile
Learn more about Primary Objects and our goals ..  More
12/22/2009
Primary Objects releases Linquify for .NET developers, LINQ to SQL library .. More
10/05/09
Primary Objects develops Prospect Tracking Portal for university .. More
Home | About Us | Services | Client Login | Job Opportunities | Contact Us
Copyright © Primary Objects 2009
Privacy Policy
Follow us on Twitter