views:

1207

answers:

3

I have an .aspx form with 20 fields that must be disable based on a users role and a status of a order record. Currently the application has 5 roles and 3 status, so I have 300 different possible conditions that I have to account for.

My first thought is to store each permutation in a table, then set the fields when the page loads by looping through the fields. Is there a better way? Please note, I am using .Net 2.0 and NOT MVC.

+2  A: 

I'd probably store the details of each field, and then the roles and status that can edit them, and do it that way.

What are the rules for the system? Basically, are there really 300 possible conditions? Or is that really certain fields are only editable for certain status, and then only certain roles can edit those fields? Or is it that certain fields are available for certain roles as well?

If it's more of the former I'd probably have something like this:

Three primary tables (makes it easy to extend if you add a field, role or status):

  • Fields
  • Roles
  • Status

Then two link tables:

  • Field.Id and Role.Id
  • Field.Id and Status.Id

Then for any given order and user you can then find which Fields are editable for the order's current status, and the users role, and as you work through the fields set the access rights appropriately - however you set the controls - either dynamically generating them based on the collection you get back, or statically on the page.

If you have an issue where the Role can override the Status, you could also store a boolean in the Field/Role table, indicating whether the Field should be avaiable regardless of status.

Zhaph - Ben Duguid
A: 

I suggest to use third party framework to achieve this. We use CSLA framework in our projects. It allow us to set authorization at field level.

Ramesh Soni
+2  A: 

Like another responder, we also use a Business Object framework called CSLA. CSLA implements field-level security checks by requiring class developers to do security checks in the property get/set calls. A typical property implementation looks like this:

Private mFirstName As String = ""
Public Property FirstName() As String
    <System.Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
    Get
        CanReadProperty("FirstName", True)
        Return mFirstName
    End Get
    <System.Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
    Set(ByVal value As String)
        CanWriteProperty("FirstName", True)
        If value Is Nothing Then value = ""
        If Not mFirstName.Equals(value) Then
            mFirstName = value
            PropertyHasChanged("FirstName")
        End If
    End Set
End Property

Notice the calls to CanReadProperty and CanWriteProperty. The second parameter specifies that the method should throw an exception if the user is not authorized to perform the specific read/write operation.

The implementation of the CanReadProperty and CanWriteProperty are provided by the framework's base class but should be reproducible without adopting the entire CSLA framework. The implementations check an AuthorizationRules data structure which defines who is allowed/denied Read/Write access based on roles. Often, the AuthorizationRules structure is populated during object creation.

Exposing the same CanReadProperty and CanWriteProperty methods to your presentation-tier allows you to enable/disable UI elements based on the current user's access rights. For example:

FirstNameTextBox.ReadOnly = Not CanWriteProperty("FirstName", false)

Hopefully this information will provide you with a good starting point for developing your own implementation. If you're interested in learning more about CSLA then check out Expert C# 2008 Business Objects.

Ken Browning