ARTICLE

Role Bases Access using VB.Net and XML

Posted by Subal Mishra Articles | Security in VB.NET August 16, 2007
Here I am trying to give a simple and configurable solution to implement Role Bases Access to your application using VB.Net and XML. Remember that this article intent is to provide Role Based Access and not Role Based Authorization.
 
Reader Level:

Role Based Access (Not Role Based Authorization):

 

Role-based access control attempts to allow administrators to specify access control in terms of the organizational structure of a company. You assign a user or a group of users to a role to perform a specific job function and restrict them to do certain other job functions.  

 

In this Role Based Access control, the administrator uses the RoleValidations.xml file to manage permissions and assignments. For example, all the fields are locked in all screens of the application for a role called Inquiry that has the read-only permissions.

 

While Input validation ensures a user only enters required, appropriate and correctly formatted values. The role based Access ensures that only permitted users can do certain specific job functions.

 

To implement the above we have used the following: 

  • An XML file to store the input field control for each screen in the application.
  • A VB class in a singleton approach that stores the XML data in cached manner and certain methods to make use of this XML based validation engine in ASP.NET pages/forms. 

The XML file (RoleValidations.xml):

 

<Validations>

  <Field>

    <Name>Invoice_Name</Name>

    <Enabled> FULL_ACCESS=true#BRANCH_ACCESS=true#INQUIRY_ACCESS=false</Enabled>

    <Visible>FULL_ACCESS=true#BRANCH_ACCESS=true#INQUIRY_ACCESS=true</Visible>

  </Field>

  <Field>

    <Name>Invoice_Commission</Name>

    <Enabled>FULL_ACCESS=true#BRANCH_ACCESS=true#INQUIRY_ACCESS=false</Enabled>

    <Visible>FULL_ACCESS=true#BRANCH_ACCESS=true#INQUIRY_ACCESS=true</Visible>

  </Field>

  <Field>

    <Name>Invoice_Save</Name>

    <Enabled>FULL_ACCESS=true#BRANCH_ACCESS=true#INQUIRY_ACCESS=false</Enabled>

    <Visible>FULL_ACCESS=true#BRANCH_ACCESS=true#INQUIRY_ACCESS=true</Visible>

  </Field>

  <Field>

    <Name>Invoice_Delete</Name>

    <Enabled>FULL_ACCESS=true#BRANCH_ACCESS=false#INQUIRY_ACCESS=false</Enabled>

    <Visible>FULL_ACCESS=true#BRANCH_ACCESS=true#INQUIRY_ACCESS=false</Visible>

  </Field>

</Validations>

 

The elements of the above XML file: 

  • <Field> defines a unique field name that defines the control name on the screen to be bind to the role access validation.
  • <Enabled> is the enabled property of the control.
  • <Visible> is the visible property of the control. 

The above XML file can be modified throughout the development process as and when the new fields are being added/removed and/or whenever any changes are requested.

 

Notice in the above XML file, the Save control/field is set true to FULL_ACCESS role as well as BRANCH_ACCESS role but the Delete control/field is set true to FULL_ACCESS role while set false to BRANCH_ACCESS role. This means that any user having the FULL_ACCESS can save as well as delete the Invoice record but the users having BRANCH_ACCESS role can only save the invoice record but cannot delete the same.

 

The Role Validation Class that loads the XML file into memory (RoleValidation.VB):

 

Imports System

Imports System.Collections.Generic

Imports System.Text

Imports System.Data

Imports System.Collections.Specialized

Imports System.Collections

Imports System.Web.Configuration

 

Namespace BusinessComponents

   

    Public Class Role

#Region "Private Fields        "

        Private Shared RoleInstance As Role = New Role()

            Private cachedRoleFields As HybridDictionary = New HybridDictionary()

        Private Const ROLE_SEPRATOR As String = "#"

        Private Const ROLE_ASSIGNMENT As String = "="

#End Region

 

#Region "Properties "

        Public Shared ReadOnly Property Instance() As Role

            Get

                Return RoleInstance

            End Get

        End Property

 

        Public Shared Function Field(ByVal fieldName As String) As RoleField

            Return (CType(RoleInstance.cachedRoleFields(fieldName), RoleField))

        End Function

#End Region

 

        ''' <summary>

        ''' Contains the structure for the RoleField

        ''' </summary>

        Public Class RoleField

            ''' <summary>

            '''  Name is the key used in the calling code to retrieve the appropriate values.

            ''' </summary>

            Public Name As String = String.Empty

 

            ''' <summary>

            ''' Control is the control Name in the respective screen

            ''' </summary>

            Public Control As String = String.Empty

 

            ''' <summary>

            ''' Collection to hold the property values either true/false

            ''' </summary>

            Public Enabled As Hashtable = New Hashtable()

 

            ''' <summary>

            ''' Collection to hold the property values either true/false

            ''' </summary>

            Public Visible As Hashtable = New Hashtable()

        End Class

 

        Private Sub New()

            '#Region "Local Variable Declaration"

            Dim Field As RoleField = Nothing

            Dim ds As DataSet = New DataSet()

            Dim RoleEnabledList As String()

            Dim RoleEnabled As String()

            Dim RoleVisibleList As String()

            Dim RoleVisible As String()

            Dim Ctr As Integer = 0

            '#End Region

 

            Try

                '#Region "Reads ScreenRoles.xml into memory"

                Dim RoleFilePath As String = WebConfigurationManager.AppSettings("RoleValidation").ToString()

                ds.ReadXml(System.Web.HttpContext.Current.Server.MapPath(RoleFilePath))

                '#End Region

 

                For Each dr As DataRow In ds.Tables(0).Rows

                '#Region "Reads through each row of the DataSet and populates a new Field object"

                    Field = New RoleField()

                    Field.Name = dr("Name").ToString()

                    Field.Control = dr("Control").ToString()

                    RoleEnabledList = dr("Enabled").ToString().Split(ROLE_SEPRATOR.ToCharArray())

 

                    '#Region "Spilting Enabled properties by role"

                    For Ctr = 0 To RoleEnabledList.Length - 1

                        RoleEnabled = RoleEnabledList(Ctr).Split(ROLE_ASSIGNMENT.ToCharArray())

                        Field.Enabled.Add(RoleEnabled(0), RoleEnabled(1))

                    Next Ctr

                    '#End Region

 

                    RoleVisibleList = dr("Visible").ToString().Split(ROLE_SEPRATOR.ToCharArray())

 

                    '#Region "Spilting Enabled properties by role"

                    For Ctr = 0 To RoleVisibleList.Length - 1

                        RoleVisible = RoleVisibleList(Ctr).Split(ROLE_ASSIGNMENT.ToCharArray())

                        Field.Visible.Add(RoleVisible(0), RoleVisible(1))

                    Next Ctr

                    '#End Region

 

                    '#End Region

 

                    '#Region "Adds the Field object to the cachedRoleFields collection."

                    cachedRoleFields.Add(Field.Name, Field)

                    '#End Region

                Next dr

            Catch ex As Exception

                Throw

            End Try

        End Sub

       

        Public Shared Sub Reset()

            RoleInstance = New Role()

        End Sub

    End Class

End Namespace

 

How to access/implement the Role Validation in web page(s): 

Suppose you have already designed your web page and placed the appropriate controls. A method named BindValidation(String role) that appears on every page of your application. The first time a page loads a call is made to BindValidation(String role),which retrieves the values from the singleton and assigns them to the screen controls.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

    If (Not IsPostBack) Then

        Dim role As String = session("role")

        BindValidation(role)

    End If

End Sub

 

Protected Sub BindValidation(ByVal role As String)

    Try

        txtAccountName.Enabled = Role.Field("Invoice_Name").Enabled(role)

        txtAccountName.Visible = Role.Field("Invoice_Name").Visible(role)

 

        cmdSave.Enabled = Role.Field("Invoice_Save").Enabled(role)

        cmdSave.Visible = Role.Field("Invoice_Save").Visible(role)

 

        cmdDelete.Enabled = Role.Field("Invoice_Delete").Enabled(role)

 

        cmdDelete.Visible = Role.Field("Invoice_Delete").Visible(role)

 

    Catch ex As Exception

        'throw;

    End Try

End Sub

The main advantage of this approach is the maintainability provided by storing the myriad of string values in a single repository. In addition, using XML means only a text editor is required to modify these values, eliminating the need for recompilation.

NOTE: THIS ARTICLE IS CONVERTED FROM C# TO VB.NET USING A CONVERSION TOOL. ORIGINAL ARTICLE CAN BE FOUND ON C# Corner (http://www.c-sharpcorner.com/).

Login to add your contents and source code to this article
share this article :
post comment
 
Become a Sponsor
PREMIUM SPONSORS
  • The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
    Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites - Click Here!
Nevron Diagram
Become a Sponsor