Friday, August 2, 2013

SharePoint 2013 REST API - Retrieving Subsites and Getting Forbidden Error, Fixed with CSOM

Recently a colleague was working on some AJAX calls using SharePoint 2013.  He needed to show all the sub-sites a user had access to in a site collection.  Up until now he was using the REST API which much success.  Getting the list of sub-sites is quite easy with REST using the following URL:


In this example I have the following site structure:
  • Root Site - All Users have access
  • Sub Site 1 - Only Administrator has access
  • Sub Site 2 - All Users have access
  • Sub Site 3 - All Users have access
So, hitting the above REST URL with an admin account produces the following:

We get back three (3) sub-sites just as expected.  Now hitting the same URL while logged in as a non-admin we would expect to get back two (2) sub-sites since we only have access to two sites.  However, we get this instead:

Bummer.  We expected that the results would just be security trimmed, but since this user does not have access to all sites, it simply returns an unauthorized message.  This message in fact:

"{"error":{"code":"-2147024891, System.UnauthorizedAccessException","message":{"lang":"en-US","value":"Access denied. You do not have permission to perform this action or access this resource."}}}"

So what to do?  Client Side Object Model to the rescue.  While using the REST API provides a much more succinct way to retrieve data, there are apparently areas where you'll need to use the more robust CSOM.

Now, the first pass at this we tried to simply load all the sub-sites using the SPWeb Webs property.  This ended up giving us the same message!  Luckily the MSDN documentation for the CSOM on the JavaScript side is coming along nicely and we found this page SP.Web.getSubwebsForCurrentUser.

This method provides a way to retrieve the sub-sites for which the user has access to and thus bypassing these errors.  Putting the example code in place we got the following while logged in as an admin:

And this while logged in as a non-admin user:

(Note:  Using IE for the admin user and FireFox for the non-admin user.  Much easier to test different permission levels this way ;) )

As you can see in the alerts, the admin sees all three sites, and the non-admin user only sees two sites.  And of course, no errors!

This method was offered up as a solution to the REST API errors:


As you can see, this URL uses the filter EffectiveBasePermissions to limit the query.  After testing in my environment, I could not get this to work.  However, one of my colleagues did have success with this filter.  So, I'm not sure where we stand on that point.  I think the REST API is great, but may not be fully baked just yet.  The good news is, if you find you have troubles with REST, you can always fall back on the CSOM.



  1. I tried the same for the Shared Documents Folder. Did not work. Any Ideas?

  2. Try This... /_api/web/Webs?$select=Title,URL,effectivebasepermissions&$filter=effectivebasepermissions/high%20gt%2032

  3. @zafar why should filter effectivebasepermission with high greater than 32 is used? What is in 32 aside from it being UseRemoteAPIs property?