Article Author: Sambeet Patra
Introduction
Designing a web based Information Management System poses a lot of challenges to developers. One of these challenges is how to provide the proper security to different users with different access to an application. Often times certain users will be allowed to update specific fields while others can only view them. It is essential to design for adequate security features in the presentation layer of your application.
This article will develop a sample Catalog Management Web Application to demonstrate the implementation of Role Based Content Rendering. I have conceptualized this application to be used by employees of various departments in an organization, each having authority to view/manage a subset of the product catalog information. With this implementation I will hide/disable various UI elements in the web pages based on the role of the current user. The aim of this solution will be to provide a simple way to maintain the UI security rules and abstract the implementation from the other parts of the application.
Note that I will not be addressing the user authorization requirements in this article. The .NET framework provides means for user authorization. Developers can also make use of the Security application block to address the authorization requirements. The security application block provides functionalities for Authentication, Authorization and Role Management (Details on this application block may be found in the related links for this article), whereas my design attempts to provide solution for "implementation" of the authorization rules to render UI. The design assumes that every user plays one or more roles in the system and each role is identified by specific role ID.
First, I will focus on storing and retrieving the security rules for rendering content. I will store my content rendering rules in a custom configuration section in the web configuration file. The rules will be read, cached and are accessed by individual user sessions.
Next, I will design a strategy to implement the rules while rendering the individual pages. One of the strong features in ASP.NET is the componentization of the web page. ASP.NET has made it possible to view each and every page element (including the page itself) as objects and to programmatically control the appearance and behavior of these objects. I will use this feature to control the content rendering. I will also abstract this implementation so that individual pages may be developed without any knowledge of how they are going to access the individual roles and check for security credentials.
In the end I will summarize the design approach and present the class diagram explaining the overall design as well as present an example that uses the framework developed.
System Requirements
To run the code for this sample you should have the following:
- A web server running Windows 2000, XP or 2003
- The .NET Framework version 1.1 or 2.0
- VS.NET 2003 or 2005
Note that the solution is compatible with .NET 2.0 / VS 2005. The code_readme.txt file provided with the code provides a set of steps to install the solution in both VS.NET 2003 and 2005.
Installing and Compiling the Sample Code
The sample download for this article contains the following:
- CatalogManagementSoln.sln – This is the VS.NET solution which contains the sample ASP.NET web project.
- CatalogManagementSoln/CatalogManagement – This is the project folder for the ASP.NET web project. The language chosen for this project is C#.
- Code_Readme.txt – A file explaining the installation and usage steps.
The code_readme.txt contains detailed steps to set up the solution in either VS 2003 or VS 2005.
The contents of the web project are explained briefly below:
- Web.config – The configuration file for the web project which also stores the access rule map information.
- Login.aspx – Page for authenticating the user and identifying the role(s) for a user.
- Product.aspx – A sample implementation of a role based content rendering is demonstrated in this page.
- ComponentConfigReader.cs – This class reads the custom configuration section in the web.config defined to store the access rule data.
- ComponentLoginMgr.cs – This class has a hardcoded implementation of the user authentication.
- ComponentPageBase.cs – The base class implementing the role based security and is inherited by individual code behinds.
- ComponentUIResourceRuleMgr.cs – Class designed to read and cache the access rule map.
The Catalog Management Application
I will start by describing the requirements for the sample Catalog Management Application. This will set the context and scope for the design in our sample application.
The Catalog Management Application is used by employees of various departments to view / update product information. The system users are shown in Figure 1.

Figure 1. Users for the Catalog Management Application
All the users shown above will be able to view / edit product information, but each of them will be able to view / edit a subset of the product attributes. Figure 2 below presents a list of product attributes along with the access rights for various users.

Figure 2. Resource access rules for the sample product page
Design Overview
The design ensures that the access rules are applied to the individual UI elements when the product page is rendered. In a conventional development scenario, the developers would probably write custom code in each page to implement the role based security. This design adds value by (a) abstracting the implementation from individual pages and (b) providing a way to change the access rules without any code changes. The snapshots of the product screen as viewed by various users are shown below in Figure 3 and Figure 4.

Figure 3. Product page as seen by a Content Administrator

Figure 4. Product page as seen by a Marketing Staff
Compare Figure 3 with Figure 4 and note the difference in the rendering of the page for two different users. The marketing staff will see a read only form (as shown in Figure 4). However, the Content Administrator will be able to view a partially editable form (as shown in Figure 3) as they can edit the product name, marketing description and the technical specification for a product. The difference in rendering here adheres to the rules specified in Figure 2. A simple approach to implement this would be to handle the rule in the code behind classes. But maintaining such code can be a time consuming task. Such implementations will also add to the budget and effort required to develop an application. Developers working on the individual web pages would rather spend their time concentrating on the application functionalities fulfilled by that page. It would be much more elegant to define the rules in a structured manner and have a common solution to implement the rules behind the scenes. That is exactly what the solution in this article will do!
Resource Access and Rule Map XML
In this section I will explain how the rules for content rendering will be stored. In other words, how the resource map defined in Figure 2 can be stored for quick retrieval.
Defining the Rule Map in XML
I will start by defining an XML structure for the access rule map and store it in a custom configuration section in the web.config file. I could also use a database for storing the rules, but I find storing data in the application configuration file (especially for static data which may change in future) results in easy maintenance.
Keep in mind that in practice you will have large number of individual UI elements. Instead of mapping each of these resources to various roles, you should map only those resources which require security. This design will assume that any UI element not mentioned in the resource map is accessible to all users by default.
Referring to the resource map list (Figure 2) I can conclude that a resource is either (1) not visible (2) read only or (3) editable to a user of the application. Hence, I will define a flag in my mapping which will have one of these values ( E for editable, R for read only and N for not visible) for each user role. Next I will define the XML for the access rules as shown in Figure 2. The role ID s I will consider are (1): Content Manager, (2) Sales Manager and (3) Marketing Staff. My resource map XML will look something like this:
<?xml version="1.0" encoding="utf-8" ?>
<Resources> <Resource ID="R_PRODUCT_NAME"> <Role ID="1" AccessType="E" /> <Role ID="2" AccessType="E" /> <Role ID="3" AccessType="R" /> </Resource> <Resource ID="R_PRODUCT_LISTPRICE"> <Role ID="1" AccessType="R" /> <Role ID="2" AccessType="E" /> <Role ID="3" AccessType="R" /> </Resource> <Resource ID="R_PRODUCT_SPECIALPRICE"> <Role ID="1" AccessType="N" /> <Role ID="2" AccessType="E" /> <Role ID="3" AccessType="R" /> </Resource> <Resource ID="R_PRODUCT_MARKETINGTEXT"> <Role ID="1" AccessType="E" /> <Role ID="2" AccessType="R" /> <Role ID="3" AccessType="R" /> </Resource> <Resource ID="R_PRODUCT_TECHSPECS"> <Role ID="1" AccessType="E" /> <Role ID="2" AccessType="R" /> <Role ID="3" AccessType="R" /> </Resource> <Resource ID="R_PRODUCT_ACTIVE"> <Role ID="1" AccessType="R" /> <Role ID="2" AccessType="E" /> <Role ID="3" AccessType="R" /> </Resource> <Resource ID="R_PRODUCT_INVENTORYQUALITY"> <Role ID="1" AccessType="R" /> <Role ID="2" AccessType="R" /> <Role ID="3" AccessType="R" /> </Resource> <Resource ID="R_PRODUCT_IMGPATH"> <Role ID="1" AccessType="E" /> <Role ID="2" AccessType="R" /> <Role ID="3" AccessType="R" /> </Resource>
</Resources>
In the XML snippet shown above, each <Resource> tag represents a unique resource identified by the <Resource ID> attribute. Inside the <Resource> tag, the access to this resource by various roles has been defined.
At this point in time, the XML mapping has nothing to do with the pages where these resources are rendered. The advantage I have with this simple mapping is that a resource may be rendered in more than one pages but I can have only one resource tag defining the security map for this resource.
Storing, Retrieving and Caching the Rule Map
The rule map will be read and cached by a singleton class. I prefer a singleton class here as a single instance of the class stays in memory and is available across user sessions for the web application. First, I will define a custom configuration section and in the web.config file as shown below.
<configSections>
<section name="ResourceMap"
type="CatalogManagement.Component.ConfigReader " />
</configSections>
Now I will include the XML in this configuration section. My config file will now look something like this.
<configSections>
<section name="ResourceMap"
type="CatalogManagement.Component.ConfigReader, CatalogManagement" />
</configSections>
<ResourceMap>
<Resources>
<Resource ID="R_PRODUCT_NAME">
<Role ID="1" AccessType="E" />
.
.
.
</Resources>
</ResourceMap>
.
.
.
Note that at the time of defining the custom configuration section, I specified the configuration section handler class as CatalogManagement.Component.ConfigReader . If you are familiar with custom configuration sections, you would know that this class will be used by ASP.NET to read and process the configuration section content. In other words this class will implement the interface IConfigurationSectionHandler . This interface has only one method Create() which is called by the ASP.NET framework whenever you attempt to retrieve the resource configuration. Here is the code for the ConfigReader class.
public class ConfigReader: IConfigurationSectionHandler
{ public ConfigReader() { } public object Create(object parent, object configContext, System.Xml.XmlNode section) { return section; }
}
Note that I am not really doing anything other than reading the configuration file in the ConfigReader class. I will process and cache the rules in a singleton class. The skeleton declaration of the singleton class will look something like this.
public class UIResourceRuleMgr
{ private UIResourceRuleMgr() { //Read the resource map upon initialization getResourceMap(); } public static readonly UIResourceRuleMgr Current = new UIResourceRuleMgr(); private Hashtable _colResourceMap = null;
}
I have made the default constructor private (which is the standard process of defining a singleton). As shown above, the single instance will be held in the static member variable called Current . This has been declared as readonly because the class will be instantiated only once. The member variable _colResourceMap stores the access rules for each resource. Out of the existing list of .NET collection classes, I have used a Hashtable as it is designed for fast retrieval of the values for a key. This is useful in web applications where you could have many UI elements.
In the constructor of UIResourceRuleMgr , I am making a call to the private function getResourceMap() to populate the Hashtable . Let’s analyze the code for this function. First, it obtains the XML structure by retrieving the custom configuration section. The ASP.NET framework makes a call to ConfigReader to obtain the configuration data.
private void getResourceMap()
{ //Instantiate the hashtable that stores the rules _colResourceMap = new Hashtable(); //Loop through the document to retrieve the map information XmlNode oConfigRoot = (XmlNode) ConfigurationSettings.GetConfig("ResourceMap"); XmlNodeList colResources = oConfigRoot.SelectNodes("Resources/Resource");
The next part of the function loops through each resource node and fills the Hashtable (one entry per node). The code for this is shown below.
foreach(XmlNode oResource in colResources)
{ string sResourceID = oResource.Attributes["ID"].Value; //Instantiate collection to hold role-access map for //this resource Hashtable colRoles = new Hashtable(); foreach(XmlNode oRoleNode in oResource.ChildNodes) { colRoles.Add( oRoleNode.Attributes["ID"].Value, oRoleNode.Attributes["AccessType"].Value); } //push the role-access collection to the resource collection _colResourceMap.Add(sResourceID, colRoles);
}
In effect, each entry in _colResourceMap will be another Hashtable of all combinations of roles and the corresponding access types defined for a given resource. A Hashtable tends to take up more memory than other collection classes, but the performance is better. I have given priority to performance here. You can design your own collection class to meet the specific requirements of your application if need be. You can take any approach as long as you are able to retrieve a list of roles and the corresponding access types for a given resource. Also, to keep the code simple, I am not handling any exceptions while parsing the XML. You may want to handle situations where the XML has invalid flags / structure. A good approach here would be to validate the XML against an XSD file.
Refreshing the Cache
Note that the cache created above will remain in memory as long as the website is up and running. What if we have to change it? Keep in mind that the rule map is placed in the web.config file. ASP.NET has the ability to track the changes made to the web.config in real time. So when you want to change the resource map, you will end up changing the web.config and ASP.NET will track this change and it will reload the application domain. This will cause the singleton class to be recreated. Thus we get a refreshed instance of the cached data in our application without any special code.
The getAccessType Method
The singleton class also provides a method to find out the access rights for a resource for the current user. This method will be called by the individual user sessions to find out the access rights of the current user on the given resource. Let’s analyze the signature of this function first.
public void getAccessType(string sResourceID, string[] colRoleID,
ref bool isVisible, ref bool isEditable)
{
}
This function is called to check access for a resource ( sResourceID ). The second argument is used to pass an array of roles the current user is assigned to. The 3rd and the 4th arguments are the access flags which are set in the function. These flags indicate if the resource is editable / read only / invisible for the current user. Before you look at the implementation of the function, keep in mind that if the user plays more than one role, then the role with the highest privilege to the resource (as defined in the resource access rule map) takes precedence in deciding the type of access to the resource. For example, if the user has two roles and the roles define read only and edit access to the resource respectively, then the highest possible access (edit) is considered. This is a general assumption made in any role driven security implementation. However, if your application has different requirements, you will need to change this code.
public void getAccessType(string sResourceID, string[] colRoleID,
ref bool isVisible, ref bool isEditable)
{
//Get the role map for the resource ID
Hashtable colRoleMap = (Hashtable)(_colResourceMap[sResourceID]);
if(null colRoleMap)
{
//No access rule defined for this resource.
//Hence assume full access
isVisible = true;
isEditable = true;
}
else
{
//find out if any role has access to this resource
for(int i = 0; i < colRoleID.Length; i++)
{
string sAccess = colRoleMap[colRoleID[i]].ToString();
if(null != sAccess)
{
if("E" sAccess)
{
//The resource is editable. This means it
//is visible too. No need to check further
isEditable = true;
isVisible = true;
break;
}
else if("R" sAccess)
{
isVisible = true;
//Continue looping through the roles as the
//resource maybe editable by other roles
}
}
}
}
}
This function will be used later at the time of implementing the security into the web page.
Implementation of the Rule Map during Content Rendering
Next I will work on implementing the rule map on individual pages. Before I explain the code, I will touch upon the ASP.NET features that I plan to use.
Use of the Page Object Model in ASP.NET
All UI elements in an ASPX page are represented as objects. This allows developers to have programmatic control on the behavior of these elements. Further, the ASPX Page is made to inherit from the code behind class which incorporates the page navigation logic. The Page object model in ASP.NET is represented in Figure 5.

Figure 5. Page object model in ASP.NET
To achieve abstraction in the design, I will make use of this object model as shown in Figure 6.

Figure 6. Introduction of the PageBase class
I have introduced a base class called PageBase whichinherits from the Page class. This class will implement the content rendering security. Individual code behinds may inherit from this page to make use of this implementation.
Note that this approach may be extended to abstract any common activities that you perform in your ASPX code behind classes.
ASP.NET Controls and Custom Attributes
Any UI element seen in an ASP.NET web page is inherited from an abstract class called System.Web.UI.Control . One way to highlight the significance of the Control class is that any UI control that is rendered will inherit the Control class. I will focus my interest on two sets of UI controls that inherit from this class. The ASP.NET server controls and the HTML controls as shown in Figure 7.

Figure 7. Classes deriving from the Control class
Both of these sets of controls support the definition of custom attributes in the control tags.
I will use the custom attribute ResourceID for all UI controls which are defined as resources in the rule map XML. An example of the product name attribute is shown below.
<asp:TextBox ID="txtName" Runat="server" MaxLength="100" Width="300px" ResourceID="R_PRODUCT_NAME" />
The resource attribute can be accessed programmatically using the Attributes collection of a WebControl or an HtmlControl. For example, if you want to access the value of a ResourceID in the textbox txtName your code will look something like this:
string sVal = txtName.Attributes["ResourceID"];
Implementation of the Rule Map
Now that I have explained the concepts used in the sample, I will describe the implementation in detail. In the PageBase class, I handle the Page initialization event as shown below.
public class PageBase : System.Web.UI.Page
{
public PageBase()
{
base.Init += new System.EventHandler(this.Page_OnInit);
}
In the event handler Page_OnInit , I parse through the control structure to identify all web / html controls with the resource custom attribute. I have to recursively drill down into the child controls for each control found in the hierarchy. By doing this I am eliminating a lot of UI elements (like the Literal controls) from being processed further. The code snippet for identifying the resources is shown below.
private void Page_OnInit(object o, EventArgs e)
{
parseControl(this);
}
void parseControl(Control oUIElement)
{
//apply security only if the control is an asp.net control or
//an html control
if(oUIElement is WebControl || oUIElement is HtmlControl)
{
applySecurity(oUIElement);
}
foreach(Control oChild in oUIElement.Controls)
{
parseControl(oChild);
}
}
Once a control is identified as a control that is inherited from the HtmlControl or the WebControl class, the ResourceID is determined to apply the security. A call to the function applySecurity() is used to do this. The first step here is to find out if the current control is a resource or not. This is done by trying to find out the definition of the custom attribute ResourceID .
void applySecurity(Control oUIElement)
{
string sResourceID = "";
//Try applying security only if it is a web control
//or html tag
if(oUIElement is WebControl)
{
sResourceID = ((WebControl)oUIElement).Attributes["ResourceID"];
}
else if(oUIElement is HtmlControl)
{
sResourceID = ((HtmlControl)oUIElement).Attributes["ResourceID"];
}
if(null != sResourceID && "" != sResourceID)
{
//I will apply security here
}
Once a ResourceID has been determined for a control we need to apply the corresponding access rule map. But before I do this, we need to consider an issue.
Recall the XML that we created previously - each resource had a list of role ids defined along with specific access types. At this point we need to know the role(s) for the current user to be able to determine their access to the resource in question. Since user authentication is not the focus of this article, a dummy implementation just to make the sample code work has been provided. The FormsAuthentication feature in ASP.NET is used to force the user to login using the Login.aspx page. I have used the FormsAuthentication tag in the web.config to set up Login.aspx as the start up page for authentication. The code snippet below displays the FormsAuthentication settings.
<authentication mode="Forms">
<forms name="CatalogManagementAuth" path="/" loginUrl="Login.aspx"
protection="All" timeout="20" />
</authentication>
The code behind the login page uses the LoginMgr class to authenticate the user. The code snippet below handles the Click event of the submit button from the login page.
private void btnLogin_Click(object sender, System.EventArgs e)
{
LoginMgr oLoginMgr = new LoginMgr();
if(oLoginMgr.isValidUser(txtUserName.Text, txtPassword.Text))
{
FormsAuthentication.SetAuthCookie(txtUserName.Text, false);
Response.Redirect("Product.aspx");
}
else
{
lblErrorMsg.Visible = true;
}
}
A dummy implementation of user authentication can be found in LoginMgr.cs . This class tries to match the login credentials to one of the hard-coded list of credentials. Upon a successful match, it retrieves the role(s) of the user (again, from a hard-coded list) and then stores them in the Session["UserRole"] .
I will present the portion of the class LoginMgr that shows the population of user roles into the user session. This implementation is hard-coded and you would provide your own authentication method in a real application. The isValidUser() function shown below is called by the Login.aspx page.
public bool isValidUser(string sUserName, string sPassword)
{
bool isValidUser = false;
string[] colRoleID = null;
//Replace this with proper authentication method
if("jmartin" sUserName && "password1" sPassword)
{
isValidUser = true;
colRoleID = new string[]{"1"};
}
else if("sparker" sUserName && "password2" sPassword)
{
isValidUser = true;
colRoleID = new string[]{"3"};
}
else if("tparks" sUserName && "password3" sPassword)
{
isValidUser = true;
colRoleID = new string[]{"2"};
}
else if("awalter" sUserName && "password4" == sPassword)
{
isValidUser = true;
colRoleID = new string[]{"1", "3"};
}
else
{
isValidUser = false;
}
//Set the role ID array in the session
if(isValidUser)
{
HttpContext.Current.Session["UserRole"] = colRoleID;
}
//return the validation result
return isValidUser;
}
The array of roles is used in the security implementation. In practice, you will want to eliminate this part completely and have your own user authentication routine defined. All that was needed for the sample application was an array of role IDs for the logged in user.
Once a valid resource is found, a call is made to the getAccessType() method defined in the UIResourceRuleMgr class. This will provide the access flags for the resource. The WebControl / HtmlControl properties are then used to disable / hide the control based on the flag. Refer to the code below for the exact implementation. This is a continuation of the applySecurity() function.
if(null != sResourceID && "" != sResourceID)
{
//Get the access flags; bool isVisible = false; bool isEditable = false; //pass the user role(s) stored in the session UIResourceRuleMgr.Current.getAccessType( sResourceID, (string[])(Session["UserRole"]), ref isVisible, ref isEditable); //Apply the flags retrieved if(!isVisible) { oUIElement.Visible = false; } else if(!isEditable) { if(oUIElement is WebControl) { ((WebControl)oUIElement).Enabled = false; } else if(oUIElement is HtmlControl) { ((HtmlControl)oUIElement).Disabled = true; } }
}
Using the Framework
The framework is now ready. The sample available for download will use it in an ASPX page to demonstrate how easily you can implement security in individual pages without really writing any extra code.
The Products.aspx page displays the attributes of a product and allows users to update the data. The rendering of the page will follow the sample mapping that we have been using so far. First thing we need to ensure is that the ASPX tags representing the product attribute should contain the proper resourceID . Here is a list of all the tags on the page.
<asp:TextBox ID="txtName" Runat="server" MaxLength="100" Width="300px" ResourceID="R_PRODUCT_NAME" />
<asp:TextBox ID="txtListPrice" Runat="server" MaxLength="30" Width="75px" ResourceID="R_PRODUCT_LISTPRICE" />
<asp:TextBox ID="txtSpecialPrice" Runat="server" MaxLength="30" Width="75px" ResourceID="R_PRODUCT_SPECIALPRICE" / >
<asp:TextBox ID="txtMarketingText" Runat="server" TextMode="MultiLine" Width="300px" Height="50px" ResourceID="R_PRODUCT_MARKETINGTEXT" />
<asp:TextBox ID="txtTechSpec" Runat="server" TextMode="MultiLine" Width="300px" Height="50px" ResourceID="R_PRODUCT_TECHSPECS" />
<asp:CheckBox ID="chkActive" Runat="server" Text=" " ResourceID="R_PRODUCT_ACTIVE" />
<asp:DropDownList ID="ddlQuality" Runat="server" Width="150px" ResourceID="R_PRODUCT_INVENTORYQUALITY"> <asp:ListItem Value="Good" Selected="True">Good</asp:ListItem> <asp:ListItem Value="Poor">Poor</asp:ListItem> <asp:ListItem Value="Needs Replacement">Needs Replacement</asp:ListItem>
</asp:DropDownList>
The only other part is to make sure that the code behind inherits from the PageBase class.
public class Product : PageBase
{
Apart from these two steps, a developer of an individual page need not worry about the security requirements for content rendering. A developer can design and develop the page assuming that each field is accessible by the user and the security is taken care by the PageBase class behind the scenes.
Changes in requirements might require a change in the rule map and the ASPX tag definitions. But the bulk of the web implementation remains unaffected.
Figure 8 presents the sequence of actions and summarizes the individual steps of the implementation as the page is loaded.

Figure 8. Sequence of activities in the implementation
Summarizing the Design
Finally let’s look at the complete design and summarize the various design components. Figure 9 presents the class diagram for the rule based content rendering.

Figure 9. Class Diagram for Role based Content Rendering
I have categorized all the classes into 3 groups, (a) the ASP.Net framework classes used in this design (b) the design elements © implementation of the design individual ASPX pages. Here is a quick summary of all the design items we discussed:
- ConfigReader – This class is the designated configuration section handler for the custom configuration section. The custom configuration section, defined in the web.config , holds the access rule map in XML. This class implements System.Configuration.IConfigurationSectionHandler and is invoked by ASP.NET when it obtains the XML rule map.
- UIResourceManager – This is a Singleton class that implements the retrieval and caching of the rule map XML in a hash table. This facilitates quick retrieval of the rules associated to a UI element.
- PageBase – This class inherits from System.Web.UI.Page . It subscribes to the Page.Init event and implements the access rule map in this event handler. It uses the Page object model to browse through the control collection and implement the security rules to the ones which have access rules defined.
- Product – This is the code behind class for the product page. It inherits the PageBase class.
- LoginMgr – This class provides a hard-coded user authentication routine that is used to demonstrate the design.
Further Work
The concept of role based content rendering may also be used with the Security Application Block from the Enterprise Library which provides a means to store roles and access information. This will replace the custom configuration section we are using in this article.
The implementation applies security only on WebControls and HtmlControls. This could be extended to User Controls, Template Controls etc. If you want to define a complex control (i.e. a user control or a container control) as a single resource, then you will need to do the followings to handle the security implementation.
- In the PageBase class, first identify the access rule for the control (editable / read only / not visible).
- If the access type is not visible, then you can use the Visible property of the Control class. If it is read only , then parse through all the child controls and whenever you encounter a web control or html control, you will need to set the Enabled property to false .
One limitation of the current design is that it does not offer an elegant solution for a Custom Control (controls that inherit from the System.Web.UI.Control ). This is because, using the control hierarchy in ASP.NET it is not be possible to disable a Custom Control.
Conclusion
In this article I first designed a mechanism for storing the access rules to render UI elements using XML. Then I used the ASP.NET Page object model and the event subscription mechanism to design a generic implementation of these rules.
Implementing authorization and role based content rendering requires considerable time and effort for web application with a lot of pages and UI elements. The design approach presented here will help you articulate a generic solution that works behind the scenes. You will not have to write chunks of code in every web page to handle security. This will improve the maintainability of your application and reduce time and cost of development.

