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

Hi,

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.

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
}


Queries, Comments and Suggestions are welcome.

Thanks.

posted @ Monday, April 25, 2005 7:42 AM

Print

Comments on this entry:

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

Left by MCM at 5/29/2008 10:18 AM
Gravatar
Correct me if I'm wrong, but doesn't this create a security problem?

Let's say you have a role called "admin" and only members of this role can access secure pages. If I edit my cookie and put "admin" in the userData section, I would gain access to the secure pages.

Now, you could encrypt the cookie which would make it far more difficult to achieve. But without verifying the cookie data with the database of roles, how can you be certain to allow the user access? Doesn't this fall under the heading of "Never trust user input"?

I'm currently working on this myself, so if I am wrong or if you have a different suggestion, I would be curious to hear it.

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

Left by azdırıcı at 11/30/2008 5:13 PM
Gravatar
yeah very good blog thanks

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

Left by mario oyunları at 9/21/2009 10:38 AM
Gravatar
you could encrypt the cookie which would make it far more difficult to achieve. But without verifying the cookie data with the database of roles

Your comment:



 (will not be displayed)


 
 
 
 
 

Live Comment Preview:

 
«November»
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345