Sharepoint 2010 : Business Connectivity Services - Adding Security Trimming to .NET Connectors

11/13/2012 3:03:32 AM
Being able to do security trimming is important in many corporations. This can be a challenge, especially if the LOB data system uses custom security descriptors. Extending the database .NET connector described in the previous section will show how this can be accomplished. Here we will assume one particular form of security descriptor, but in reality it could be in any format that supports mapping between the user context and the descriptor.

First a rights table must be added to the model to support security trimming. Here we have created a CustomerAccessRights table containing the SecurityDescriptor, Rights, and CustomerKey. The SecurityDescriptor is a binary unique value for a particular user. Rights will contain a simple numeric schema representing user rights to a particular row. It also contains creation rights.

  • Read Allowed

  • Read / Write / Update / Delete Allowed

No Entry means the user has no rights to this data row represented by the CustomerKey. In a production environment, a different and more fine-grained access rights mapping might be desired, but this should give a good idea about how to implement security trimming that allows multiple users with different access to the same data rows. Given the customer table contains this information, we can create a CustomerAccessRights table containing the security mappings. The SecurityDescriptor should be based on the same method used by the model to trim security. In this example, it is the GetSecurityDescriptor() method displayed in Tables 1 and 2.

Table 1. Customers Table
2Microsoft555-xxxxxx1mail@microsoft.com JohnDoe
5SurfRay555-xxxxxx2mail@surfray.com JohnDoe
6Apple555-xxxxxx3mail@apple.com JohnDoe
7IBM555-xxxxxx4mail@ibm.com JohnDoe

Table 2. Customer Access Rights Table
1 2 <binary data>
2 2 <binary data>
2 5 <binary data>
2 6 <binary data>
2 7 <binary data>

To add the CustomerAccessRights table to the model, add a new LINQ to SQL Classes item to the project and name it CustomerAccessRights. In the Server Explorer, add a connection to the Customers database if it does not already exist. Then drag the CustomerAccessRights table, and drop it on the CustomerAccessRights.dbml design surface.

Next the required method for computing the SecurityDescriptor is added as in Listing 1. This method can be added to the CustomerService.cs class that also contains the Customer methods. This method computes a security descriptor in the form of a byte array.

Example 1. Implementation of Method for Getting a Security Descriptor
static Byte[] GetSecurityDescriptor(string domain, string username)
     NTAccount acc = new NTAccount(domain, username);
     SecurityIdentifier sid = (SecurityIdentifier)acc.Translate(typeof(SecurityIdentifier));
     CommonSecurityDescriptor sd = new CommonSecurityDescriptor(false, false,
          ControlFlags.None, sid, null, null, null);

     sd.SetDiscretionaryAclProtection(true, false);


//Deny access to everyone
     SecurityIdentifier everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
     sd.DiscretionaryAcl.RemoveAccess( AccessControlType.Allow, everyone,
           unchecked((int)0xffffffffL), InheritanceFlags.None, PropagationFlags.None);

     //Grant full access to specified user
     sd.DiscretionaryAcl.AddAccess( AccessControlType.Allow, sid,
           unchecked((int)0xffffffffL), InheritanceFlags.None, PropagationFlags.None);

      byte[] secDes = new Byte[sd.BinaryLength];
      sd.GetBinaryForm(secDes, 0);

      return secDes;



Having the Rights table and the security descriptor method in place, the next step is to modify the Customers methods for updating, reading, etc., such that they are trimmed based on the security descriptor. Here (Listing 2) the Reader methods are updated to apply security trimming during search.

Example 2. Adding Security Trimming to the BDC Method Instances
public static IEnumerable<Customer> ReadList()
    CustomerDataContext context = new CustomerDataContext();
    CustomerAccessRightsDataContext accessContext = new CustomerAccessRightsDataContext();

    List<Customer> tempCustList = new List<Customer>();
    foreach(Customer customer in context.Customers)
       CustomerAccessRight custAccess = accessContext.CustomerAccessRights.SingleOrDefault(
             c => c.CustomerKey == customer.CustomerKey  && c.SecurityDescriptor.ToArray()
             == GetSecurityDescriptor(Environment.UserDomainName,Environment.UserName));

        if(custAccess.Rights > 0)

     IEnumerable<Customer> custList = tempCustList;
     return custList;

 public static Customer ReadItem(string customersKey)
      CustomerDataContext context = new CustomerDataContext();
      Customer cust = context.Customers.Single(c => c.CustomerKey == customersKey);

      CustomerAccessRightsDataContext accessContext = new CustomerAccessRightsDataContext();


CustomerAccessRight custAccess = accessContext.CustomerAccessRights.SingleOrDefault(
          c => c.CustomerKey == cust.CustomerKey && c.SecurityDescriptor.ToArray()
          == GetSecurityDescriptor(Environment.UserDomainName, Environment.UserName));

      if (custAccess.Rights > 0)
          return cust;
          return null;


Using this methodology as a baseline, it is possible to create simple security trimming. When doing security trimming, performance of the trimming mechanism is relevant. Different caching mechanics can be applied with success to increase performance. Also other security descriptor implementations that better fit specific requirements can be implemented using this example as a template for how to approach the topic. Microsoft does provide some resources on this topic.

Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8