SharePoint 2010 Custom WCF Service CPU Spike

The Problem

On a client site this week after deploying a solution involving a custom WCF service intermittent CPU spikes were recorded – 50% firstly, then maxing out at 100%.

We were unable to reproduce the issue… until it was reported that one user attempting to access the service didn’t have appropriate access to the site that the WCF service called.

There was no unauthorized 401 response, the actual method within the service gets called in the context of the logged-in user, who is authenticated on the domain. 

The asynchronous WCF service method itself is permitted to be called by a domain user (from a Silverlight client in this instance) until such a time as a SharePoint query is executed and appropriate authorization is required. For example, if the WCF service method simply returned some unsecured or non-SharePoint data, there should have been no problem.

The hosted WCF service (using MultipleBaseAddressBasicHttpBindingServiceHostFactory) fails miserably presumably due to the sequence of events which lead up to the SharePoint authorization check, by which point the HTTP authorization response has been returned to the client. Anybody who fully understands why this fails so miserably and/or can confirm my suspicions please let me know!

The Solution

The solution was to add a check for appropriate user permissions as follows, wrapped in an Elevated Privileges section – hardly rocket science but it took a while to debug this one with verbose custom logging in the Unified SharePoint Logs to work out what the problem was!

All relevant methods now include a check for appropriate permissions as follows:

private bool CurrentUserHasReadPermission
		{
            get
            {
                bool HasReadAccess = true;
                try
                {
                    SPSite siteColl = SPContext.Current.Site;
                    SPWeb web = SPContext.Current.Web;

                    string strUsername = HttpContext.Current.User.Identity.Name;

                    SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                        using(SPSite elevatedSiteColl = new SPSite(siteColl.ID))
                        {
                            using (SPWeb elevatedWeb = elevatedSiteColl.OpenWeb(web.ID))
                            {
                                if (!elevatedWeb.DoesUserHavePermissions(strUsername, SPBasePermissions.ViewPages))
                                {
                                    HasReadAccess = false;
                                }
                            }
                        }

                    });

                }
                catch (UnauthorizedAccessException)
                {
					// Unauthorized access
                    HasReadAccess = false;
                }

                return HasReadAccess;
            }
        }

 

Hope that helps somebody!

Leave a Comment Yourself

Your email address will not be published. Required fields are marked *