Setting Up Permissions at the ListItem Level in SharePoint 2010 Using CSOM
In his latest post, App Dev Manager Dennis Kim discusses an approach to set up permissions at a ListItem level in SharePoint 2010 using the Client-Side Object Model (CSOM). He also discusses ways to mitigate performance issues associated with ListItem management.
For the most part, it’s not advisable to attempt managing SharePoint permissions at the ListItem level. The obvious reason is that as the contents of the list start to grow, so do the associated processing requirements needed to manage the ListItems. Imagine trying to programmatically examine permissions for 10,000 ListItems.
Better yet, imagine trying to assign and delete dozens of unique permissions off each ListItem in a list and we rapidly approach the domain of transaction counts in the millions. And yet SharePoint gives users the option to manage permissions at such a fine granularity because scenarios will arise in which elevated security controls are required, particularly in the government and finance sector.
This article will examine one approach to set up permissions at a ListItem level in SharePoint 2010 using the Client-Side Object Model (CSOM) and ways to mitigate performance issues associated with ListItem management.
***This approach assumes that permissions are being applied at the ListItem level for the first time or that ListItem permissions are drastically out of synch with the desired end state. Otherwise, if the current state of permissions closely resembles that of the desired end state, a more surgical approach using REST to identify the deltas may be more appropriate. Similarly, this approach works best when the target list contains a large number of ListItems and when each ListItem contains a large number of erroneous permissions that must be removed. It is up to the development team to evaluate how their permissions are structured and determine if this approach is appropriate for their list data.
It’s worth considering why a development team might choose to leverage CSOM in the first place instead of the SharePoint Server Object Model (SSOM) or the Representational State Transfer (REST) interface.
In some development sites, local development teams are so far physically divorced from the SharePoint farm and its administration team that repeatedly loading and executing code becomes prohibitively burdensome; this is especially true of government sites. In this case, the ability to run code client-side offers development teams an agile way of testing and deploying code rapidly and independently, so long as web service access to CSOM’s API endpoints are allowed. As a caveat, bear in mind that executed CSOM code will run at the security level of the account used to execute the code which can introduce added complexity in terms of account security.
On the other hand, SharePoint’s REST interface offers an even more light weight approach than CSOM. However, CSOM is better suited for managing SharePoint ListItems because it is naturally designed to batch requests and send them to the server as large payloads whereas REST tends to send smaller requests but more frequently. This difference in server communication is sometimes described as “chunky” versus “chatty”, CSOM versus REST. In light of the sheer volume of transactions that can be expected in managing permissions at the item level, the overhead processing involved in REST operations makes it incredibly inefficient when compared to CSOM.
Even with the batch processing offered by CSOM, performance remains a major concern. One of the things we can do to reduce the overall amount of processing needed is to identify if there are any core permissions that are shared among all ListItems. If so, an efficient way of assigning these permissions would be to set the core permissions at the List level before breaking role inheritance at the ListItem level. If you suspect there are ListItems within the list that have already broken inheritance, it’s worth it to reset role inheritance just to ensure that all ListItems conform to a common baseline. From there you can iteratively set unique permissions on each ListItem. Here’s what the general steps for this approach might look like:
Step 1 – Reset role inheritance for every ListItem in the list (if you suspect rogue ListItems)
Step 2 – Remove all permissions and add core permissions
Step 3 – Break role inheritance for every ListItem. When doing this, ensure that the copyRoleAssignments parameter is set to ‘true’ to ensure that the core permissions are inherited
Step 4 – Assign unique permissions to each ListItem
Invariably, even after eliminating the need to assign core permissions individually, the final step of assigning unique permissions will likely require a tremendous amount of processing and it’s possible to discover here that setting up permissions at the list item level is not viable. Before making that determination, make sure you are not introducing performance issues with your code. Here are a couple things to look for:
- Invoke the contextual ExecuteQuery() method as infrequently as possible. The fewer ExecuteQuery() calls you make, the larger the batches you send to the server for processing thereby effectively leveraging CSOM’s batch processing model. In particular, avoid calling ExecuteQuery() inside for-loops. For example, when breaking role inheritance on ListItems, it may be tempting to write your code in the following way:
However, a better alternative is to place the ExecuteQuery() call outside the for-loop:
When batching server requests together, it’s possible to do it so well that the batch becomes too large to manage and the server is unable to process the request or simply time-out. A low-tech way of managing batch sizes is by creating a simple counter that calls the ExecuteQuery method after a set number of iterations:
Be sure to still include a final ExecuteQuery outside the for-loop to pick up the last set of requests.
- When accessing resources, only request what you need. When loading objects this means requesting only the properties you need:
When pulling list data, this means querying only the columns that are needed:
There are an abundance of other ways in which you can enhance the performance of a CSOM script. However, within the context of setting up ListItem permissions in SharePoint 2010, the aforementioned strategies will go a long way towards building a viable solution.