Custom XSL Web Part Error – Access Denied

Scenario:

I created a custom XSL style sheet for a library web part that would intermittently throw an error for everyone except the admin account (me).

Every morning users were complaining about an error on the web part. I would sign in and try to replicate, but it always worked for me. Then when I’d ask the user to refresh their page and miraculously the error would go away.

Error

ULS logs contained the following information:

SPSecurityContext: Could not retrieve a valid windows identity for username ‘domain\user’ with UPN ‘user@domain.local’. UPN is required when Kerberos constrained delegation is used. Exception: System.ComponentModel.Win32Exception (0x80004005): Access is denied Server stack trace:
 at System.ServiceModel.Channels.AppContainerInfo.GetCurrentProcessToken()
 at System.ServiceModel.Channels.AppContainerInfo.RunningInAppContainer()
 at System.ServiceModel.Channels.AppContainerInfo.get_IsRunningInAppContainer()
 at System.ServiceModel.Channels.PipeSharedMemory.BuildPipeName(String pipeGuid)
 at System.ServiceModel.Channels.PipeSharedMemory.get_PipeName()
 at System.ServiceModel.Channels.PipeConnectionInitiator.GetPipeName(Uri uri, IPipeTransportFactorySettings transportFactorySettings)
 at System.ServiceModel.Channels.NamedPipeConnectionPoolRegistry.NamedPipeConnectionPool.GetPoolKey(EndpointAddress address, Uri via)
 at System.ServiceModel.Channels.CommunicationPool`2.TakeConnection(EndpointAddress address, Uri via, TimeSpan timeout, TKey& key)
 at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
 at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
 at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
 at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
 at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
 at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown
 at [0]:
 at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
 at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
 at Microsoft.IdentityModel.WindowsTokenService.S4UClient.IS4UService_dup.UpnLogon(String upn, Int32 pid)
 at Microsoft.IdentityModel.WindowsTokenService.S4UClient.CallService(Func`2 contractOperation)
 at Microsoft.SharePoint.SPSecurityContext.GetWindowsIdentity().
No windows identity for “domain\user”.

Root cause:

The SharePoint site’s application pool was configured to recycle every morning at 3:00 AM. This would clear cached authentication, and due to permissions, the XSL style sheet could not be accessed until the administrator logged in.

In addition, according to Hemendra’s response in this post, this can also be caused by an anonymous cache bug.

Solution:

Option 1: Remove auto-recycle settings on the application pool. (The error will re-appear if the site is manually recycled or the server reboots.)

Option 2 (recommended): Create two separate XSL files. The first file will be attached to the web part and, using the xsl:import element, will reference a second XSL file that contains your view styles.

XSL File #1 – Reference.xsl (linked in the Web Part Properties):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:import href="/SiteAssets/Style.xsl"/>

<xsl:template match="/">
<xsl:apply-imports/>
</xsl:template>

</xsl:stylesheet>

xsllink

XSL File #2 – Style.xsl (contains view styles):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<tr>
<td><xsl:value-of select="catalog/cd/title"/></td>
<td><xsl:value-of select="catalog/cd/artist"/></td>
</tr>
</table>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

NOTE: Save your XSL files in a library where Everyone has at least Read permissions.