Authorization Rules Anomalies!

Authorization Rules Anomalies!

Old forum URL: forums.lhotka.net/forums/t/3433.aspx


david.wendelken posted on Monday, August 27, 2007

I confess!  With so much to learn, I've been going along filling in the Authorization rules by rote, without really taking the time to think about how it works under the hood.

Now I want to load up the authorization rules from a database instead of hard-coding them in each business class.  So I really started looking into it and found a few conceptual surprises.

Property level authorization rules are the province of an individual business object class.   They are stored in classes designed for that purpose.

Object level authorization rules are the province of a collection business object class, not the individual business object class.  For example (and forgive the gooberish nature of the example):

Party contains the authorization rules for PartyId, PartyName, PartyPhone, PartyEmail, etc.

PartyList contains the authorization rules for adding, editing, deleting or getting Party objects, not Party.

So, if I were to create two different collection business objects for Party, I could have different authorization rules for each list.  For Example:

In this scenario, I might be able to add customers but not vendors.  (Presumably the collection class is doing some extra work to mark a party added via the CustomerList collection as a Customer.)

Is this sort of situation the reason why the collection class, and not the business object it contains, maintains this type of authorization rule?  (It seems to me that this type of situation could get one in a lot of hot water very quickly!).


I can clearly see why CanAddObject is a static method. 

Given that individual properties can be turned off on a per-instance level, it also makes sense to me that CanEditObject could be a static method.  After all, the per-instance situation could be handled by negating the ability to edit any of the properties.  They UI experience in that situation would be a bit clunky, but it would not produce incorrect results.

Ditto for CanGetObject.

CanDeleteObject is more problematic.  I might have the authority to delete objects in general, but not this object in particular.  How are others doing that in the CSLA framework?


Or is the reason for this because of some quirk of .Net databinding?

Or is it just a matter of "Hey, this is a big framework to build, document and test, and Rocky didn't have time to do more on this subject?"

Anyone know of a good reason why we shouldn't move these decisions to the business objects contained in the collection?

 

 

The authorization roles for individual properties in a business object appear to be stored in in a Dictionary collection.

But the authorization roles for the business object itself (add, delete, edit and get) are not stored in any memory structure.  Instead, they are hard-coded as static methods on the business object's collection object.   For example, ProjectList would have:

public static bool CanEditObject()
{
    return someHardWiredAnswer;
}

 

 

stefan replied on Tuesday, August 28, 2007

Hi David,

I am currently implementing db-based authorization in my CSLA-App, so I will answer on this topic:

Location of object-level-authorization-rules:
I think object-level-authorization-rules belong to root objects, wheter they be collections or not.
Your example indicates that party is a child object, and the objects that manage the retrieval/persistance of parties are your Collections (CustomerList, VendorList, ...).

You could implement CustomerList.CanAddObject. But that would lead to the impression of CustomerList containing editable objects. I would avoid that confusion.
If you do, I would delegate the authorization query to a Customer/Vendor object, which would be root objects.

Per-instance-authorization-rules:
I still cannot see any situation where instance-authorization-rules, as they are implemented in the framework at the moment, would make any sense. The instance-rules are set during creation of the object instance. At that moment no business-property-values have been set, so there is no chance of authorizing based on any instance-specific data.

CanDeleteObject vs. CanDeleteInstance:
The former answers the question whether the current user can delete certain types in general, so we can arrange the UI-navigation accordingly. I think it makes sense caching this information.
The latter provides us with the current user's authorization with respect to a specific instance of a type.

I am retrieving the type-level-authorization-rules during login, and store them in a static/shared dictionary. I looked at how Rock implemented the AuthorizationRulesManager/SharedAuthorizationRules and got my 'SharedClassPermissions'

Here's some code to think/argue about:

In MyBusinessBase.vb:
    Public Shared Function CanDelete(Of TObject)() As Boolean
        Return MyBaseLib.Security.GetAccessInfo(GetType(TObject), MyBaseLib.Security.ClassAccessLevel.CanDelete)
    End Function

In MyBaseLib.Security:
    Puplic Shared Function GetAccessInfo(ByVal objectType As Type, ByVal accesslevel As ClassAccessLevel) As Boolean

        Dim result As Boolean = False
        Dim manager As ClassPermissionsManager = SharedClassPermissions.GetManager(objectType, False)

        If Not manager Is Nothing Then
            Dim theconfig As ClassAuthorizationConfig = manager.ClassPermission
            Return ClassAuthorizationConfig.checkIfAny(theconfig.Config, accesslevel)
        End If

        Return result

    End Function


Hope this is of some help.

Stefan


Copyright (c) Marimer LLC