Prevent Un-authorized modifications in SAF

There is an issue currently with SAF (Simple Authorization Framework) when it is used for entities in Entity Framework. The issue is that when SAF reads an entity and tests it against the user principal, it would modify the properties which user has no read access to null. There are also properties that uses hos no edit access which Saf can notify the client about it but does not do anything at this stage to prevent un authorized edit on objects with partial permission.

For example if you modify a book object, which you can edit the title, but are not allowed to edit the price, there is no check on the server to make sure you haven’t done so. I call this partial edit access. If you don’t have edit access to the book object, then Saf prevents you from changing any thing.

Supporting partial edit access for entity framework is not hard, but you should be very cautious of doing so due to possible performance implications. In a 3 tier architecture, you don’t keep the object context alive for the whole session, thus, the original object is not kept anywhere when the service is called back for an update. The way EF ensures optimistic concurrency is that it compares all values inside the sql update statement for the fields with CuncurrencyMode set to Fixed to ensure data is not modified in the background, if there has been any modification to the data, a conflict exception is thrown and user has the choice to resolve the conflict.

However, we don’t have the luxury of implementing the authorization checks to the SQL statement, because Saf does not know how to create Sql queries. Instead, we have to load the actual object in the datastore and ensure that modifications are valid. This is possible by using GetObjectByKey method on the ObjectContext:

var oc = ...// the object context
var storeObject = oc.GetObjectByKey(((IEntityWithKey)modifiedObejct).EntityKey);
//Compare properties of the storeObject with modifiedObject to ensure no un- authorized
//change has happened

Above code can compare the store values with current values for properties of which user has no edit permission. Obviously there is a performance hit problem with this approach because an extra query is sent to the database for each modification that involves partial edit or view access on an object. There is also another issue with this approach; the logic here conflicts with the logic of optimistic concurrency check. For example if user has no view access to the price of the book, Saf will put null in the price field. When data is sent back to the server, context assumes that the object is modified and tries to write back the null value. If we replace the null with current store value, un-authorized properties are changed back, but what happens if someone else has changed these properties before? There should be a conflict, but we have overwritten that conflict with our authorization logic.

Therefore, I am still no sure if I should implement this as part of the Saf solution.

Alternative solution is to check the modified properties using some code similar to this:

var unauthorizedProps = ...; //List of unauthorized properties
var modiProps = objContext.ObjectStateManager.GetObjectStateEntry(modifiedObj).GetModifiedProperties().ToList();
//Mark the object unchanged
objContext.ObjectStateManager.ChangeObjectState(modifedObj, EntityState.Unchanged);
foreach(var prop in modiProps.Except(unauthorizedProps))

Above code would find all the modified properties, filters out just authorized ones, sets the entity as unmodified and markes the authorized props to be modified. This is much better performer than the previous approach. One of these approaches may eventually find their way through Saf if there is no better way to manage this issue.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: