by December 1, 2004 0 comments



Last month we had a look at what role-based security in .NET framework is all about and how we can leverage it in our applications using the ‘System.Security.Principal’ namespace and its contained classes.

Let’s move a step ahead and see how we can create roles and identities that are specific to our application and its security subsystem. This is made available, in the .NET framework, by exploring the notions of ‘GenericPrincipal’ and
‘GenericIdentity’, which also reside in the ‘System.Security. Principal’ namespace.

Check out the code for this article at http://forums.pcquest.com/developer

Why custom security?
Whenever we are creating applications, particularly for the enterprise, there is always a need to secure the kind of work a user can do with the application. In simpler terms, this boils down to understanding the capabilities and requirements of the user depending upon their role, and then allowing or disallowing them application functionality access.

Direct Hit!
Applies to: .NET developers
USP: Customized role-based security for applications
Links:
http://tinyurl.com/3uhkx 

For instance, a user who is member of the administrators group on a Win XP machine can start or stop background services, using the ‘Service Control Panel applet’. However, a user who is member of the ‘Users’ group cannot do so. This is an example of functionality control depending upon who you are. In our last article, we talked about identifying users and their groups, provided they logged in on Win NT architecture based (Win 2000/XP/Server 2003) machine.

However, most business applications don’t rely on the underlying OS’s users/groups to allow or disallow access to application’s functionality. Instead, they have their own user account list and, at times, a user-to-group mapping to help them identify what parts of the application can be used by a logged in user, depending upon their group.

Introducing generic APIs
To achieve the same effect in the .NET framework, the .NET framework exposes ‘GenericIdentity’ and ‘GenericPrincipal’ classes that are functionally similar to the ‘WindowsIdentity’ and ‘WindowsPrincipal’ classes, except they can be used against your applications usernames and group lookups to implement a custom role-based security solution.

We start off by creating a custom identity for our application, based upon a username and authentication scheme that’s specific to our application:

public GenericIdentity(
string username,
string authenticationtype
);

Next, we create a ‘Principal’ object using the identity that we created above:

public GenericPrincipal(
IIdentity identity,
string[] roles
);

To create a ‘GenericPrincipal’ we need two things:

  • An object that implements ‘IIdentity’ interface. We get this by specifying the ‘GenericIdentity’ object we instantiate as ‘GenericIdentity’ class implements ‘IIdentity’ interface.
  • An array of role/group names, which correspond to the specified identity. Once this is done, all that remains is to set the currently executing thread’s security context to that of our ‘GenericPrincipal’ and this is done as shown below.

// set our threads’s security principal
Thread.CurrentPrincipal = gpCurUser;

A security exception being thrown when the user Anusha, not a manager, attempts to invoke a method only managers can invoke

‘gpCurUser’ is the ‘GenericPrincipal’ object that we created. With our custom-security infrastructure in place, we now need to simply create ‘PrincipalPermission’ objects, execute a Demand against them and the CLR’s security subsystem shall automatically do the role-based security checks and will allow the code execution to go ahead conditionally. Below is an example of doing so.

PrincipalPermission refPerm = new PrincipalPermission(
arrUsers[0],
arrRoles[0]
);
refPerm.Demand();

Implementing
The code accompanying this article exemplifies the concepts we have discussed above and puts them in action. It’s a very simple application that assigns a specified group to a user, depending upon their username (of course, in real-life application there will be much more complexity in determining the user/group mapping!).

Next we create our custom identity and principal objects, set our thread’s security context and then invoke certain methods, depending upon the user’s input. The catch here is that some methods that can be invoked by user belong to the ‘Manager’ role; only regular application users can invoke some; while some can be invoked by users in ‘Guest’ role.

Each of the methods does these role-based checks using the ‘PrincipalPermission’ objects and in case there is a failed check, a security exception is thrown.

Where to from here?
We have so far seen how to leverage role-based security support in the .NET framework, for both Windows- authenticated users and application specific custom-authenticated users.

But role-based security is just one part of the security subsystem of the .NET framework. CAS (Code Access Security) is a more powerful security system that allows even more granular control over code execution, access, inheritance and more.
Next month, we shall continue our foray into the .NET framework security by working with CAS.

Gaurav Khanna
wintoolzone.com

No Comments so far

Jump into a conversation

No Comments Yet!

You can be the one to start a conversation.

<