Project Description

Provides an interface based approach to allowing the implementation of fine grained access control using a Reference Monitor

Works seamlessly to provide object level protection with Entity Framework and can easily be added to other libraries or systems as required

Reference Monitor Overview

A reference monitor is an approach to implement a secure system based on access control. Any system can be depicted in terms of subjects, objects, an authorization database, an audit trail, and a reference monitor, as shown in Figure 1. The reference monitor is the control center that authenticates subjects and implements and enforces the security policy for every access to an object by a subject.

Refer to how a reference monitor works 1 or 2.

reference-monitor.png

Usage Overview

Allows access via the following protections, each of which provides Read,Write,Execute,Delete
  • System
  • Owner
  • Group
  • World

In the simplest case we call ReferenceMonitor.IsPermitted to ascertain whether a user (subject) can perform an operation to an object.

e.g.
if (!ReferenceMonitor.IsPermitted(Zaretto.Security.Operation.Create, currentUser, currentObject))
    throw new Exception("Cannot create a new object").


Usage in Entity Framework

/// <summary>
/// check the permissions during save changes
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Entities_SavingChanges(object sender, EventArgs e)
{
    var osm = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager;

    foreach (var addedObject in osm.GetObjectStateEntries(System.Data.EntityState.Added))
    {
        ReferenceMonitor.ThrowIfNotPermitted(Operation.Create,
                                                currentUser,
                                                addedObject as IControlledObject);
    }

    foreach (var modifiedObject in osm.GetObjectStateEntries(System.Data.EntityState.Modified))
    {
        ReferenceMonitor.ThrowIfNotPermitted(Operation.Write,
                                                currentUser,
                                                modifiedObject as IControlledObject);
    }

    foreach (var modifiedObject in osm.GetObjectStateEntries(System.Data.EntityState.Deleted))
    {
        ReferenceMonitor.ThrowIfNotPermitted(Operation.Delete,
                                                currentUser,
                                                modifiedObject as IControlledObject);
    }
}

/// <summary>
/// check the permission of every object that is materialized - only those that implement IControlledObject will be checked
/// as the reference monitor doesn't check null objects or subjects
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
{
    ReferenceMonitor.ThrowIfNotPermitted(Operation.Read, 
                                         currentUser, 
                                         e.Entity as IControlledObject);
}


Usage in DataOjbects.net

        protected override void OnGettingFieldValue(Xtensive.Orm.Model.FieldInfo field)
        {
            if (DisablePermissionsChecking)
                return;

            // don't check access to fields of type protection or permission- otherwise we can never use these for
            // checking permissions of an object that we don't have access to.
            // also shouldn't really check fields that are used inside the reference monitor
            if (field.ValueType.FullName == "DomainModel.Protection"
                || field.ValueType.FullName == "DomainModel.Permission"
		|| field.Name == "Id" 
		|| field.Name == "BaseGroup"
                )
                return;

            base.OnGettingFieldValue(field);

            skipSecurityCheck = true;

    ReferenceMonitor.ThrowIfNotPermitted(Operation.Read, 
                                         currentUser, 
                                         this as IControlledObject);

            skipSecurityCheck = false;
        }

        protected override void OnSettingFieldValue(Xtensive.Orm.Model.FieldInfo field, Object value)
        {
            if (skipSecurityCheck || DisablePermissionsChecking)
                return;

            base.OnSettingFieldValue(field, value);

            skipSecurityCheck = true;
 ReferenceMonitor.ThrowIfNotPermitted(Operation.Write,
                                                currentUser,
                                                this as IControlledObject);
            skipSecurityCheck = false;
        }

Last edited Nov 29, 2015 at 7:52 AM by RichardHarrison, version 8