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.

Print | posted on Monday, April 25, 2005 7:42 AM

Comments on this post

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

Requesting 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.
Left by MCM on May 29, 2008 10:18 AM

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

Requesting Gravatar...
yeah very good blog thanks
Left by azdırıcı on Nov 30, 2008 5:13 PM

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

Requesting 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
Left by mario oyunları on Sep 21, 2009 10:38 AM

Your comment:

 (will show your gravatar)