ASP.NET Role Based Security: The Basics
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)
}
}
No comments:
Post a Comment