"Knowledge has to be improved, challenged, and increased constantly, or it vanishes."

Access Denied Error, when retrieving user profiles count from SharePoint

Recently for one of my SharePoint project implementation, I wanted to list the number of user profiles available in SharePoint. So I added the following code.

             SPSecurity.RunWithElevatedPrivileges(
                    delegate()
                    {
                        using (SPSite thisSite = new SPSite(SPContext.Current.Site.Url))
                        {
                            SPServiceContext serviceContext = SPServiceContext.GetContext(thisSite);
                            UserProfileManager mgr = new UserProfileManager(serviceContext, true);
                            users.Text += "The total number of user profiles available:  " + mgr.Count;
                        }
                    }
                );

When I run the code, I got the following error.

Access Denied: Only an administrator may retrieve a count of all users.

The code that is running under RunWithElevatedPrivilages thrown access denied error. So I decided to check whether my application pool identity has enough permission for user profile service application. From central administration site, under application management navigate to Manage service applications.

clip_image002

In the service applications page, Select the user profile service application row and click administrators from the top menu.

clip_image004

In the administrators list, I was able to see the application pool identity and found the application pool identity have full access to user profiles.

clip_image005

This created some confusion in me, is there any problem with RunWithElevatedPrivileges? After some hours of search in the internet, it seems the UserProfileManager doesn’t support impersonation. It seems it is using the identity from HttpContext, which will not be changed while using RunWithElevatedPrivileges. So one option is to impersonate the HttpContext. The following post gives an outlook of how to perform the HttpContext impersonation.

https://go4answers.webhost4life.com/Example/impersonating-spservicecontext-26108.aspx

Another option is to make the HttpContext to null, then execute the code and then reset the HttpContext. So I tried this option and the code started working. See the code I used

              SPSecurity.RunWithElevatedPrivileges(
                    delegate()
                    {
                        using (SPSite thisSite = new SPSite(SPContext.Current.Site.Url))
                        {
                            HttpContext tmp = HttpContext.Current;
                            HttpContext.Current = null;
                            SPServiceContext serviceContext = SPServiceContext.GetContext(thisSite);
                            UserProfileManager mgr = new UserProfileManager(serviceContext, true);
                            users.Text += "The total number of user profiles available:  " + mgr.Count;                               
                            HttpContext.Current = tmp;
                        }
                    }
                );

This produced the below output.

The total number of user profiles available: 4

Basically to read user profile, by default every authenticated users have permission to read user profile data. So you don’t need elevated privileges to display user profile properties. But if you need to get access to user profile as administrator to retrieve count, or update the profile data of another user etc. you can use the above workaround.

No Comments