|
The role-based security model
The C# Column - Yashavant Kanetkar
Role-based
security is an elegant way to provide user authorisation and user
access checks for our application. We must first understand what
‘role’ means in the security vocabulary. A role is a set of users
sharing the same security privileges. A user belonging to a particular
role can access code, software and resources for which permissions
are granted for the role.
Granting permissions to
access resources/code using roles rather than using a particular
user is easier to manage. For example, suppose an application grants
permission to access a particular feature to four users. Now, if
the number of features grow to ten, the application would need to
decide which user to grant permission to access which feature and
add the permissions accordingly. If the application uses role-based
security, it needs to only declare that the users belonging to a
particular role can access a feature. Another important thing to
note is that the role-based model works without walking the stack.
Before we learn more about role-based security, let us first see
what stack walks entail.
Stack walk
Stack walks are an essential
part of the security system. Here’s how a stack walk operates: Every
time a method is called, a new activation record will be put on
the stack. This record contains the parameters passed to the method
(if any); the address to return to when this function completes;
and, any local variables. At certain stages during execution, the
thread might need to access a system resource, such as the file
system. Before allowing this access, the protected resource may
demand a stack walk to verify that all functions in the call chain
have permission to access the system resource. At this stage a stack
walk will occur and each activation record is checked to see that
callers do indeed have the required permission.
Principal
In case of role-based security,
the code can perform actions based on the data it collects about
the user. It is best when used in conjunction with Windows 2000
accounts. The heart of role-based security lies in the Principal
(identity and role of the user). Role-based security is most useful
in situations where access to resources is an issue. Consider a
bank, where everyone needs to log into a particular software program
in order to use it. Access to records will depend on the role of
the user trying to access it. A clerk will login with a different
role than the manager, hence he will not be allowed access to personal
data of various customers, whereas the manager might have the powers
to modify the records if necessary. These situations are very common
and hence .NET provides easy ways to implement security on the basis
of roles. .NET allows developers to use role-based security as attributes,
freeing the business logic from the responsibility of performing
security checks.
Let us now put the role-based
security model to work in an application. This application retrieves
personal information about employees, which is stored in a database.
A user will be allowed to view the database only if he has an administrative
login on that computer.
Create a Windows application
and design the form as shown below:

Change the names of the
controls as shown in the following table:
|
Control
|
Name |
|
Employee ID
First Name
Last Name
City
Lookup button
Exit button
|
Empid
Fname
Lname
City
Lookup
Exit |
Also add the Click event
handler for the ‘Lookup’ button. Add the code given below in this
handler.
private void lookup_Click ( object sender,
System.EventArgs e )
{
SqlDataReader dr = null ;
SqlConnection con = new SqlConnection ( (
@"server=(local)\ NetSDK;
Trusted_Connection=yes;
database=backup" ) ) ;
SqlCommand com = new SqlCommand ("Select
* from Employees", con );
con.Open( ) ;
dr = com.ExecuteReader( ) ;
while ( dr.Read( ) )
{
if ( empid.Text == dr [ "EmployeeID" ]
.ToString( ) )
{
fname.Text = dr [ "FirstName" ].ToString(
);
lname.Text = dr [ "LastName" ].ToString( );
city.Text = dr [ "City" ].ToString( );
}
}
con.Close( );
}
Here, we have created three
basic objects required to deal with the database—dr, com
and con of type SqlDataReader, SqlCommand and
SqlConnection respectively. We have then used the ExecuteReader(
) method of the command object to execute the command and collected
the result in dr. Then we have iterated through the record
set till we find the record whose Employee ID matches with the one
user has asked for. Once the record is found, it’s displayed it
in the text boxes.
Add an event handler for
the Load event and write code in it as given below.
private void Form1_Load ( object sender, System.EventArgs
e )
{
AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.WindowsPrincipal
);
WindowsPrincipal p = ( WindowsPrincipal ) Thread.CurrentPrincipal
;
lookup.Enabled = p.IsInRole ( WindowsBuiltInRole.Administrator
);
}
In this handler, to begin
with we have set the principal of the current application domain.
The method SetPrincipalPolicy( ) is used for this purpose.
To access the current domain we have used the CurrentDomain
property of the AppDomain class. It returns a reference to
the application domain in which our application is running. We have
passed the PrincipalPolicy.WindowsPrincipal to this method.
PrincipalPolicy is
an enumeration in the System.Security.Principal namespace.
Principal Policy enumeration holds three types: NoPrincipal,
UnauthenticatedPrincipal and WindowsPrincipal. Of
these three, the WindowsPrincipal holds the identity of the
current user logged on to Windows.
In the next statement we
have created a reference
to an object of type WindowsPrincipal. The WindowsPrincipal
class is capable of holding all information about a Windows account
holder. The reference is made to point to the identity of the current
user.
In the previous statement
we have setup the principal policy of the current application domain
to the current user. Since our application thread is executed inside
the current application domain, CurrentPrincipal property
of the thread will hold the same value that we setup for the whole
application domain in the previous statement.
This much just to access
the Windows identity of the current user. Now we must check whether
or not the role of the current user is that of the Administrator.
The WindowsPrincipal object we have referenced above has
a method IsInRole( ) which compares the role of information
it holds with the one that has been passed to it.
We have passed the WindowsBuiltInRole.
Administrator role to this method to check whether the user
belongs to the Administrator group. If IsInRole( ) returns
true, it means that the user is actually a member of the
Administrator group and hence the Enabled property of the
‘Lookup’ button is set to true to allow user to look up the
employee’s information. Otherwise the button is disabled.
If the role of the user
using this program is not ‘Administrator’, then the interface will
look as shown in the following snapshot:

Lastly, add the Click
event handler for the ‘Exit’ button and call the Dispose(
) method from it to close the form. Note that we must use System.Threading,
System.SqlClient and System.Principal namespaces to
run the program.
 |
Yashavant Kanetkar, one of the first
Express Computer columnists, is an established software expert,
speaker and author with several best-sellers to his credit,
including titles like “Let Us C” and the “Fundas” series. Contact
him at kanet@nagpur.dot.net.in |
|