Click here to Skip to main content
Click here to Skip to main content

Authenticate User by Roles in ASP.NET

, 25 Aug 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
A simple forms authentication strategy in ASP.NET with example web site

Introduction

Forms authentication enables user and password validation for Web applications that do not require Windows authentication. With forms authentication, user information is stored in an external data source, such as a Membership database, or in the configuration file for an application. Once a user is authenticated, forms authentication maintains an authentication ticket in a cookie or in the URL so that an authenticated user does not need to supply credentials with each request.

At my web site, I have a folder "Admin", which I only want users with administration roles to be able to access. I simply don't want to check each user's right on this folder, just depends on roles. This article is about this approach.

Background

In my case, I don't care who has logged into my website, if they are not logged in, they can only browse my web site; if they registered and logged in, they can do certain things, like add a fire panel, delete the fire panel they created; if users logged in with administration roles, web site will grant them rights to access files under "admin" folder.

Using the Code

Download the code, unzip it to a folder, create a virtual directory on IIS for it. Root directory contains "login.aspx","logout.aspx","default.aspx", and a folder called "admin". At "admin", there is only one file, "default.aspx" - this is the file I will stop normal user from accessing.

Forms authentication includes several important parts you need to implement.

At my web.config file, I set Authentication mode to "Forms".

At web.config, I create a folder that I want to authenticate user as follows:

<location path="Admin">
	<system.web>
		<authorization>
			<allow roles="Administrators"/>
       <deny users ="*"/>
		</authorization>
	</system.web>
</location>
<authentication mode="Forms">
    <forms name="AuthCookie" path="/" loginUrl="login.aspx" 
		protection="All" timeout="30">
      <!--<credentials passwordFormat="Clear">
        <user name="Lewis" password="llllll"/>
      </credentials>-->
    </forms>
  </authentication>	

Please remember to put <allow roles="Administrators" /> before <deny users="*" />, otherwise no one will be able to access folder "admin".

Forms authentication "login" URL is "login.aspx", you can change whatever file you like.

At credentials section, I used to have several users that I want to authenticate, and use asp:LoginView web control to show their login status, it turn out to be not very flexible. I abandoned it, instead by using Roles, and this is where this article comes from. This way I can create users, save them to database, assign them "Administrators" roles, they will be able to access my "Admin" folder.

OK, the next thing is to create a web site structure. Here I used "web.sitemap", you can add it by selecting Visual Studio 2008's add new item option.

At "web.sitemap" file, I created several SiteMapNode with "Administrators" roles as follows:

  <?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
    <siteMapNode url="~" title="Home"  description="">
        <siteMapNode url="default.aspx" title="Home"  description="" roles="*"/>
      <siteMapNode url="login.aspx" title="Login"  description="" roles="*"/>
      
      <siteMapNode url="Admin/" title="Administration"  description="" roles ="*" >
        <siteMapNode url="Admin/default.aspx" title="Administration"  
		description="" roles ="Administrators" />
      </siteMapNode>
      <siteMapNode url="logout.aspx" title="Logout"  description="" roles="*"/>
    </siteMapNode>
</siteMap>

In my default.aspx, I used Repeater, and SiteMapDataSource controls to make my web site more maintainable. On my real web site, I used Repeater, SiteMapDataSource and SiteMapPath controls at master page, which makes the whole web site look more clean and tidy.

When the user first sees this web site, they can see "Administration" hyperlink, click on it, IIS's FormsAuthentication object will navigate user to "login.aspx" page because of "Web.Config" file's setting, asking user to Login.

Type in user name, password, check it through various methods, database access in my case, user authenticated, grant certain user "Administrators" roles as follows:

FormsAuthenticationUtil.RedirectFromLoginPage("Lewis", "Administrators", true); 

FormsAuthenticationUtil is a third party DLL, it creates an authentication ticket for user, change user's log in status to Logged In. Later on, I stopped using this DLL. Because I need to have full control of user's Login process.

I created a User class which especially handles user's Login and Registration process, etc. A snippet of code:

public static void CreateTicket(ENetUser newUser,bool persistantCookie)
{
    string roles = "users";
    if (newUser.Email.ToLower().Trim() == "abc@hotmail.com" ||
        newUser.Email.ToLower().Trim() == 
		"john.dole@pertronic.co.nz") roles = "Administrators";
    roles += "," + newUser.ID;
    roles += "," + newUser.ID;
    
    // Create a new ticket used for authentication
    FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
       1, // Ticket version
       newUser.UserName, // Username associated with ticket
       DateTime.Now, // Date/time issued
       DateTime.Now.AddMinutes(30), // Date/time to expire
       persistantCookie, // "true" for a persistent user cookie
       roles, // 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
    System.Web.HttpContext.Current.Response.Cookies.Add(cookie);
}

As you can see, I created a ticket for user, add a cookie to user's PC. When user accesses our web site the next time, we recreate the user's ticket from that Cookie.

The above code is not in the example code, it is a hint "FormsAuthenticationUtil" is done, I think.

The next thing is that you need to tell the web application how to authenticate users. I added the following lines to global.asax, if you do not have that file in your web root directory, add it by selecting "add new item" from Visual Studio 2008 "Web Site" menu.

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 GenericPrincipal(id, roles);
            }
        }
    }
} 

As you can see, once users have logged in, they will be authenticated, but they do not have our "Administrators" roles yet. We use the above routine assign that role.

We are done.

As I mentioned above, the example didn't show how to read the above cookies from PC. The reason I need to do this is that I want to save user's time of logging in each time they opened up my web site.

At my web site, the following code was added to "global.asax", at session start, read cookie, give user a ticket, Application authenticate method will use that ticket to grant user "administrators" role.

void Session_Start(object sender, EventArgs e)
{        
    HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    if (cookie != null)
    {
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
    }
}

FormsAuthentication.FormsCookieName is defined in web.config's "Forms" section.

History

  • 26th August, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Lewis Liu L
Software Developer
Australia Australia
If you think this article is useful, please donate using paypal:
https://www.paypal.com/au/webapps/mpp/make-online-payments
 
by using my email: yyiu002@hotmail.com

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141220.1 | Last Updated 26 Aug 2010
Article Copyright 2010 by Lewis Liu L
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid