Access Denied Messages when retrieving SharePoint User Profiles Count even running in Elevated code

This is another tricky one. And I think I had this problem long time ago which I had this workaround but couldn’t remember about it until I’ve looked into an old code snippet.

Here’s the scenario.

You need to retrieve the total number of user profiles in SharePoint. The API has a property for that in the UserProfileManager class. You could just write some code like this:


UserProfileManager profileManager = new UserProfileManager(serviceContext);
long ProfileCount = profileManager.Count;

But the problem is that in order to retrieve this you need to have admin privileges on the User Profile Service. So the logical way of doing this is to run the code with Elevated privileges and ensure the identity used by the application pool of your site has admin privileges on the User Profile service. So I’ve tried that using the code below:


SPSite siteColl = SPContext.Current.Site;

try{
  SPSecurity.RunWithElevatedPrivileges(delegate()
  {
    using (SPSite ElevatedsiteColl = new SPSite(siteColl.ID))
    {
      SPServiceContext serviceContext = SPServiceContext.GetContext(ElevatedsiteColl);
    UserProfileManager profileManager = new UserProfileManager(serviceContext);
    ProfileCount = profileManager.Count;
    }
  });
}
catch (Exception ex)
{
  LogException(ex);
}

Testing the code running under an Admin account it was fine (because it was the same account used by the site’s application pool). But when I tested the code using a regular user this code should still run fine (because I was running it elevated). Unfortunately that’s not what happened. For some weird reason seems that the SharePoint API was trying to impersonate the current user thus throwing an exception and showing an Access Denied error which said  Access Denied: Only an administrator may retrieve a count of all users.

So after sleepless nights (just kidding it was just some banging my head on the wall), I finally remembered to take a look at an old code snippet that I had when facing the same issue in the past, and I’ve decided to write this post (blog posts are a great way to use as a diary).

The Workaround

Basically my workaround is to set the current HttpContext to null inside the code, but keeping the existing context in a temp variable so I can revert it back once I run the snippet. You have to revert it back to the original context otherwise you are going to get a lot of errors. The code looks like this: 

SPSite siteColl = SPContext.Current.Site;
HttpContext tempCtx = HttpContext.Current;

try
{
SPSecurity.RunWithElevatedPrivileges(delegate() {
using (SPSite ElevatedsiteColl = new SPSite(siteColl.ID))
{
SPServiceContext serviceContext = SPServiceContext.GetContext(ElevatedsiteColl);
HttpContext.Current = null;
UserProfileManager profileManager = new UserProfileManager(serviceContext);
ProfileCount = profileManager.Count;} });
}
catch (Exception ex){ LogException(ex);}
finally{ HttpContext.Current = tempCtx;}

Using the code above I could retrieve the count even using a regular user (no admin access) .

 I hope this saves some time on your side and avoid some head banging on the wall

Have a nice one !

Andy Nogueira.

About these ads

6 responses to “Access Denied Messages when retrieving SharePoint User Profiles Count even running in Elevated code

  1. Hey Andy, thanx a lot for the post. Unfortunately I discovered your post AFTER I’ve got my head bruised from banging it against the wall. I ran my under elevated priviliges but didn’t think about the httpcontext….studpid my. Thanx for sharing knowledge.

  2. Thanks for sharing! Solved my problem!

  3. Nice blog….Saved our time… Thanks…

  4. Similar story to your’s and Nicolai’s – probably blown about 6 hours changing app pool ids, different perm sets…. before I found your post and solved it.
    Many thanks.

  5. My story is just like everyone else’s story above and you saved the day.. thanks for this Andy !

  6. Awesome…you saved my day…and potentially many dead cells from cursing and getting angry with Microsoft for not making it well documented. The solution I’m developing is for FBA. It redirects users to their specific subsite after they log in in the customized login page. The subsite string is stored in their user profile. Anyone is interested in the source, you can email me at 10011111b@gmail.com

Leave a Reply

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

WordPress.com Logo

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

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s