Geeks With Blogs

News Ashraful Alam Joy

Create Your Badge

Ashraful Alam is a Software Architect, who has 8 years of professional experience in Software Development industry. This Bangladeshi national is involved with project management and development of several US based software projects from his country. Already he has managed and developed several software projects, which are being used by several users of different countries, such as USA, Canada, Australia, and Bangladesh. While developing and managing a team, he contains and maintains a set of well defined engineering practices developed by him and other online developer communities.

Due to his willingness to give effort to improve and share better software development practices, Ashraf has been awarded as “Most Valuable Professional” (MVP) in ASP.NET category by Microsoft since year 2007 multiple times, which is a rare honor and prestigious reorganization among the developers around the world.

Check his portfolio to know more about him and his works.


.NETTER Characters... Every part of your life is best, if you can know yourself and thus create your life like an artist!

Authentication and authorization is the two basic part of the user-end security in asp.net web applications. After to successful authentication of a user, authorization takes the place according to which the authenticated user are allowed to access to the corresponding resources in the web application.

Role based security is very basic requirements in the current trend of web applications. Mostly there are two roles involved, which are registered user and the admin users. However in a web application a user can have multiple roles which can be authorized on page and page control level. Today we'll check a basic sample which includes page based authorizations for specific roles.

To implement the basic role based security, there are three points to be considered. In this example we are considering two different roles "member" and "admin". There are two separate folders named "member", which can be accessed by any logged in user, including admin users and "admin", where only the user who contains the "admin" role can access the child resources (page, images etc).

1. Defining the authorization regions in web.config

The following xml tags are required to be added under the "configuration" node of the web.config.

Defining security authorization for "member" users

  <location path="member">
    <system.web>
      <authorization>
        <deny users="?"/>
      </authorization>
    </system.web>
  </location>

Defining security authorization for "admin" users

  <location path="admin">
    <system.web>
      <authorization>
        <allow roles="admin"/>
        <deny users="*"/>
      </authorization>
    </system.web>
  </location>

2. Authenticating the user

After the successful authentication, the following codes are required to establish the form based authentication for the corresponding user.

//Authenticating the user Identity. 
System.Web.Security.FormsAuthentication.RedirectFromLoginPage
("member1", this.CheckBox1.Checked);

3. Implementing the role based security

The "Application_AuthenticateRequest" event which was defined in the "Global.asax" file, will include the appropriate codes regarding the role info of the logged in user, which will be accesses each time for any web request in this web application. This can be done in either "cache" or "cookie" mechanism.

Cache based mechanism

    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
 
        if (HttpContext.Current.User != null)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
 
                if (HttpContext.Current.User.Identity.AuthenticationType != "Forms")
                    throw new Exception("Only forms authentication is supported, not " +
                        HttpContext.Current.User.Identity.AuthenticationType);
 
                System.Security.Principal.IIdentity userId = HttpContext.Current.User.Identity;
 
                //if role info is already NOT loaded into cache, put the role info in cache
                if (System.Web.HttpContext.Current.Cache[userId.Name] == null)
                {
                    string[] roles;
                   
                    if (userId.Name == "admin1")
                        roles = new string[1] { "admin" };//this info will be generally collected from database
                    else if (userId.Name == "member1")
                        roles = new string[1] { "member" };//this info will be generally collected from database
                    else
                        roles = new string[1] { "public" };//this info will be generally collected from database                  
                   
                    //1 hour sliding expiring time. Adding the roles in chache. This will be used in Application_AuthenticateRequest event located in Global.ascx.cs file to attach user Principal object.
                    System.Web.HttpContext.Current.Cache.Add(userId.Name, roles, null, DateTime.MaxValue, TimeSpan.FromHours(1), System.Web.Caching.CacheItemPriority.BelowNormal, null);
                }
               
                //now assign the user role in the current security context
                HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(userId, (string[])System.Web.HttpContext.Current.Cache[userId.Name]);
            }
        }
 
    }
 
Cookie based mechanism 
 
 
    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
        if (HttpContext.Current.User != null)
        {
            if (Request.IsAuthenticated == true)
            {
                if (HttpContext.Current.User.Identity.AuthenticationType != "Forms")
                    throw new Exception("Only forms authentication is supported, not " +
                        HttpContext.Current.User.Identity.AuthenticationType);
 
                //Create/Retrieve cookie and initizalyze the role info in the current security context
                string userInformation = String.Empty;//where the cookie info will be placed
                string[] roles;//where the user role will be placed
 
                // Create the roles cookie if it doesn't exist yet for this session.
                if ((Request.Cookies["cnstUserRole"] == null) || (Request.Cookies["cnstUserRole"].Value == ""))
                {
                    if (HttpContext.Current.User.Identity.Name == "admin1")
                        roles = new string[1] { "admin" };//this info will be generally collected from database
                    else if (HttpContext.Current.User.Identity.Name == "member1")
                        roles = new string[1] { "member" };//this info will be generally collected from database
                    else
                        roles = new string[1] { "public" };//this info will be generally collected from database                   
 
                    // Create a string to persist the role and user id
                    userInformation = roles[0] + ";" + Context.User.Identity.Name;
                    // Create a cookie authentication ticket.
                    FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
                        1,                              // version
                        User.Identity.Name,             // user name
                        DateTime.Now,                   // issue time
                        DateTime.Now.AddHours(1),       // expires every hour
                        false,                          // don't persist cookie
                        userInformation
                        );
 
                    // Encrypt the ticket
                    String cookieStr = FormsAuthentication.Encrypt(ticket);
 
                    // Send the cookie to the client
                    Response.Cookies["cnstUserRole"].Value = cookieStr;
                    Response.Cookies["cnstUserRole"].Path = "/";
                    Response.Cookies["cnstUserRole"].Expires = DateTime.Now.AddMinutes(1);
 
                }//if role cookie not found in local pc
                else//we are getting the role info from cookie
                {
                    // Get roles from roles cookie
                    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Context.Request.Cookies["cnstUserRole"].Value);
                    userInformation = ticket.UserData;
 
                    //info[0] contains the single role and info[1] contains the user name
                    string[] cookieInfo = userInformation.Split(new char[] { ';' });
                    roles = new string[1] { cookieInfo[0] };
                }
 
                //now assign the user role in the current security context
                Context.User = new System.Security.Principal.GenericPrincipal(Context.User.Identity, roles);
 
            }//if (Request.IsAuthenticated == true)
        }
    }
 

Download source code:


Posted on Monday, February 18, 2008 4:31 PM Implementation , Architecture , Database , .NET , Software Development | Back to top


Comments on this post: ASP.NET Role Based Security: The Basics

# re: ASP.NET Role Based Security: The Basics
Requesting Gravatar...
so cool! very helpful!
Left by Taeyo on Apr 24, 2008 8:31 AM

# re: ASP.NET Role Based Security: The Basics
Requesting Gravatar...
Basically, I'm holding a list of
roles in a database for each user. Once the user has got past the
login form, the Application_AuthenticateRequest fires. In there, I'm
doing a database lookup on the user and then creating a
GenericPrincipal using the User's Identity and the array of roles.
It's great, it works, cool.

UNFORTUNATELY, IT RUNS EVERY TIME THE PAGE IS LOADED. So that's a
database lookup every time a page is requested - not good enough. I
can't even store the array of roles in a Session variable because you
don't get access to the session variable in
Application_AuthenticateRequest ,

I wish to keep my roles in the db, and I don't want to keep a list of
users and passwords in the web.config file, or read them out of an XML
file ('cos that would be the same problem).

Any suggestions?
Left by Shruti on Sep 25, 2009 2:46 AM

Your comment:
 (will show your gravatar)


Copyright © Ashraf Alam | Powered by: GeeksWithBlogs.net