|
An ordinary VB developer shares his own successes and failures |
|
||||||||
| Home News Articles Resources Tips Downloads About me | ||||||||||
.NET InterceptionUsing the .NET interception plumbing to add access control functionality to an existing monolithic application.The application I'm going to talk about in this article is a rather simple one (at least from an architectural point of view). It's used to analyze, display and amend data representing concentrations of various air pollution agents measured at stations spread throughout the Slovak republic (see screenshot - 219 KB, Slovak language only ).
The data from the stations are collected and consolidated into one huge SQL Server database, which the application reads and updates directly.
Although the application is monolithic, I was fortunate
enough
(
An
A The application has been used for a couple of months already, when I've got a request to implement a new feature - authorization and access control:
Upon startup, the application should present a logon dialog
box and validate the user name and password entered against
a new
Each row in the
Any other value (or missing user record altogether) should cause the application to terminate.
After some thinking, I realized that the access rights
represented by the 6th character of the
A new
The
A new The access control algorithm itself was designed with extensibility in mind. Because I'm in love with table-driven algorithms, I have chosen a table-driven approach.
The logic is encapsulated in a new
Public Class AccessControlGuard
Private Shared _MethodToPropertyMap As New Hashtable
Shared Sub New()
_MethodToPropertyMap.Add("MarkValuesInvalid", "CanModifyDataAttributes")
_MethodToPropertyMap.Add("UpdateMinValues", "CanModifyDataValues")
_MethodToPropertyMap.Add("ApplyLineConstants", "CanModifyDataValues")
_MethodToPropertyMap.Add("MultiplyValues", "CanModifyDataValues")
_MethodToPropertyMap.Add("UploadMeasuredValues", "CanModifyDataAttributes")
End Sub
Public Shared Function CanExecuteMethod( _
ByVal method As String) As Boolean
' Lookup the UserToken property name that must
' return True in order to allow the method to execute.
Dim PropName As String = CStr(_MethodToPropertyMap(method))
If PropName Is Nothing Then
' The method is not in our table so by definition,
' we allow it to be executed (it is not data modifi-
' cation method) as long as the user token has ANY
' access to the application.
Return Not App.User.NoAccess
End If
' Invoke the property through reflection.
Dim PropInfo As PropertyInfo = App.User.GetType().GetProperty(PropName)
Debug.Assert(Not PropInfo Is Nothing)
Return CBool(PropInfo.GetValue(App.User, Nothing))
End Function
Public Shared Sub AccessCheck( _
ByVal method As String)
If Not CanExecuteMethod(method) Then
Throw GetAccessDeniedException()
End If
End Sub
...
End Class
The last very important question remains: How to incorporate
the access checks into the existing Measurement class?
The 'classic' approach would be to add the appropriate
But I didn't do it that way. Recently, I've read a couple of articles about interception in .NET, and this project seemed to be an ideal medium to try the concepts by hand. So I went out and implemented the interception code according to recommendations found in the great article "Decouple Components by Injecting Custom Services into Your Object's Interception Chain", by Juval Lowy (see links).
Here are the implementation steps for adding interception to
the existing
1. I've implemented the Public Class AccessControlServerSink Implements IMessageSink2. I've implemented the AccessControlProperty class, which
injects the AccessControlServerSink into the Measurement's
context:
Public Class AccessControlProperty Implements IContextProperty Implements IContributeServerContextSink3. I've implemented the AccessControlAttribute class, which
has to be associated with our Measurement class and which
adds the AccessControlProperty to the context:
<AttributeUsage(AttributeTargets.Class)> _ Public Class AccessControlAttribute Inherits ContextAttribute4. I've derived the Measurement class from
ContextBoundObject class and I've applied the
AccessControlAttribute to it:
<AccessControl.AccessControl()> _ Public Class Measurement Inherits ContextBoundObjectHere is the complete code for the classes: I've built the project, tested with sample data and all kinds of users - everything went well. I was excited!
I've started to write this article eager to share with you
how easy is to implement interception in .NET. I didn't
finish the article, however, because I had to go home (my
wife called me that we are supposed to visit our
friends... That was yesterday. Today I came to work to do some more testing and finish the article eventually. I've run some tests with real data and I've to say that my excitement was gone. The application turned to be way too slow!
This is not surprising at all, given the way the
So in the end, I had to remove the interception-related code
and I've added the access check to the prolog of every
relevant This is certainly not to say that interception is slow. I still think it's a great technique provided the associated performance penalty is negligible. Remote marshal-by-reference objects, for example, are good candidates for interception, because they are accessed through proxy anyway. So be careful when considering using interception in your own project. You have to take into account the associated performance overhead. If you are not sure, a quick prototype might be in order. After all, adding the interception code is easy (once you grasp the details, of course). Obligatory warning: Most of the classes and interfaces discussed here and in the articles referred bellow are officially undocumented, so use them at your own risk. Nevertheless, the fact that they are described in the MSDN Magazine's article might say something, IMHO. © Palo Mraz, Sunday, August 31, 2003 Linkshttp://msdn.microsoft.com/msdnmag/issues/03/03/ContextsinNET/default.aspx - great article about .NET contexts and interception.http://msdn.microsoft.com/msdnmag/issues/02/03/AOP/default.aspx - describes a custom COM interception framework and relates it to the .NET approach. http://oko.shmu.sk/ - air pollution in the Slovak Republic. |
||||||||||
|
|
||||||||||
| ©2003-2007 Palo Mraz. All Rights Reserved. See my 'new browser window' policy | ||||||||||