C# Tutorials and offshore development in India
    Tutorials   Resources   Forum   Communities   Interview   Jobs   Projects   Offshore Development    
Silverlight Tutorials | Mentor | Code Converter | Articles | Code Factory | Computer Jokes | Members | Peer Appraisal | IT Companies | Bookmarks | Revenue Sharing |


Prizes & Awards
My Profile



Active Members
TodayLast 7 Days more...

New Feature: Community Sites: Create your own .NET community website and start earning from Google AdSense ! It's Free !




Setting Role cookie at the Application Level in Role Based Authorization - Forms Authentication


Posted Date: 13 Sep 2006    Resource Type: Articles    Category: Web Applications
Author: Harish RanganathanMember Level: Gold    
Rating: Points: 10



Introduction


Forms Authentication and Role based authorization are one of the best ways in implementing a robust authentication / authorization model for your web applications when developing using ASP.NET.

Role based Authorization and Application_Authenticate Method


When using Role Based Authorization, we can set the Roles of a user at the application level by specifying it in the Global.asax's Application_AuthenticateRequest method.

As soon as a user is authenticated, it will fetch his roles from the database and assign it to him so that we can use the User.IsInRole("RoleName") to check his role and perform actions based on the same.

You can find many resources on the above topic on how to set the roles. However, one disadvantage is that on every page you check the Role, the DB call is made which might affect the performance of the application.

Resolution


To resolve that we can set the role cookie manually through code so that it doesnt make the DB call for every request.

The following code segment provides the code for the total operation.


In the Global.asax's code behind file, locate the following method and put the code inside as follows:-

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
AssignRolesToUser();
}


Then place the following code segment.


private void AssignRolesToUser()
{
if (Context.Request.IsAuthenticated)
{
// Retrieve user's identity from context user
FormsIdentity ident = (FormsIdentity) Context.User.Identity;



// Retrieve roles from the authentication ticket userdata field

string[] roles = ident.Ticket.UserData.Split('|');



// If we didn't load the roles before, go to the DB

if (roles[0].Length == 0)

{

// Fetch roles from the database.

roles = FetchRoles();



// Store roles inside the Forms ticket.

FormsAuthenticationTicket newticket = new FormsAuthenticationTicket(

ident.Ticket.Version,

ident.Ticket.Name,

ident.Ticket.IssueDate,

ident.Ticket.Expiration,

ident.Ticket.IsPersistent,

String.Join("|", roles),

ident.Ticket.CookiePath);



// Create the cookie.

HttpCookie authCookie = new HttpCookie(

FormsAuthentication.FormsCookieName,

FormsAuthentication.Encrypt(newticket));

authCookie.Path = FormsAuthentication.FormsCookiePath + "; HttpOnly; noScriptAccess";

authCookie.Secure = FormsAuthentication.RequireSSL;



if (newticket.IsPersistent)

authCookie.Expires = newticket.Expiration;



Context.Response.Cookies.Add(authCookie);

}



// Create principal and attach to user

Context.User = new System.Security.Principal.GenericPrincipal(ident, roles);

}

}







private string[] FetchRoles()

{

// Fetch roles from the database somehow.

ArrayList roleList = new ArrayList();

SqlDataReader objRdr=null;



SqlConnection objCon = new SqlConnection("Your connection string here);

SqlCommand objCmd = new SqlCommand("spRoles", objCon);

objCmd.CommandType = CommandType.StoredProcedure;

objCmd.Parameters.Add("@Username", User.Identity.Name.ToString());

try

{

objCon.Open();

objRdr = objCmd.ExecuteReader();

if(objRdr.HasRows)

{

while(objRdr.Read())

{

roleList.Add(objRdr["RoleName"].ToString());

}

}

objRdr.Close();

}

catch

{

return null;

}

finally

{

objCon.Close();

objCon.Dispose();

}

return (string[])roleList.ToArray (typeof (string));

}

The procedure spRoles will fetch the roles based on the UserName which is passed as a parameter.

The code for the procedure is as below:-

CREATE PROCEDURE spRoles

(

@Username varchar(50)

)

AS



SELECT G.Name

FROM Roles R

INNER JOIN Groups G ON

R.GroupID = G.GroupID

INNER JOIN Users U ON

R.UserID = U.UserID AND U.Username = @Username

In the above procedure I have used three sample tables Users, Groups and Roles

Users - will contain UserID, UserName and password
Groups - will contain GroupID and Name i.e. Admin, Moderator, User
Roles - will contain the UserID and their GroupID i.e. group they are assigned to.


Once you set the above Roles, thereafter in your pages, you can just use

if(Context.User.IsInRole("RoleName"))
{
// do something
}


Summary


This article explained how we can set the role cookie at the application level to ensure that there is a Database hit avoided for each page.




Responses


No responses found. Be the first to respond and make money from revenue sharing program.

Feedbacks      
Popular Tags   What are tags ?   Search Tags  
(No tags found.)

Post Feedback


This is a strictly moderated forum. Only approved messages will appear in the site. Please use 'Spell Check' in Google toolbar before you submit.
You must Sign In to post a response.
Next Resource: ASP.NET Application Deployment - Performance Enhancement
Previous Resource: Error: "It is an error to use a section registered as allowDefinition='MachineToApplication'....
Return to Discussion Resource Index
Post New Resource
Category: Web Applications


Post resources and earn money!
 
Related Resources



dotNet Slackers   BizTalk Adaptors    Web Design


Contact Us    Privacy Policy    Terms Of Use