Word Automation BatchGetSyncJobStatus does not work when requesting a security token

I am using a SharePoint 2013 based server on which I deployed a simple WCF service as a farm solution. The service accepts simple Http mail requests that contain individual MS Word documents as a payload and returns these files converted to PDF files. The service is available through Http for anonymous users. WordAutomationService acts as the SharePoint server administrator account.

The service class creates a new instance of Microsoft.Office.Word.Server.Conversions.SyncConverter and passes the SharePoint proxy running WordAutomationService to the constructor (along with some ConversionJobSettings). Finally, he calls the Convert method on SyncConverter with an input stream (Word document) and an output stream (web response that will contain the resulting PDF document created by WordAutomationService).

When creating a SyncConverter, I do not set the UserToken property because the service is accessed by anonymous users. As noted here https://msdn.microsoft.com/en-us/library/microsoft.office.word.server.conversions.syncconverter.usertoken.aspx this looks ok:

The default value for this property is a null reference (Nothing in Visual Basic), which is anonymous.

This setting is great for small Word documents with multiple pages and returns the expected PDF files. But as soon as the execution time of the WordAutomationService in SharePoint exceeds a certain time threshold (about 5 seconds), the service fails because it never returns (which leads to a read timeout on the client). According to the logs, it seems that the reason is that after a while the synchronous conversion task moves the work to the background process:

Stream job conversion synchronization takes too much time. Don't wait anymore. Check his status later

He then regularly checks the status of this job by calling ConversionServiceApplicationProxy.BatchGetSyncJobStatus. Unfortunately, this call fails because it is trying to create a new channel to discuss this process, and this requires a security token. However, SecurityTokenService cannot fulfill the request for the token and throws an exception:

An unhandled exception has occurred. The security token request cannot be completed. System.InvalidOperationException: The security token request cannot be completed. at Microsoft.SharePoint.SPSecurityContext.SecurityTokenForServiceContext(Uri contextUri) at Microsoft.SharePoint.SPChannelFactoryOperations.InternalCreateChannelActingAsLoggedOnUser[TChannel](ChannelFactory`1 factory, EndpointAddress address, Uri via) at Microsoft.Office.ConversionServices.Service.ConfigChannelFactory`1.CreateChannel(EndpointAddress address) at Microsoft.Office.ConversionServices.Service.ConversionServiceApplicationProxy.GetChannel(Uri uri) at Microsoft.Office.ConversionServices.Service.ConversionServiceApplicationProxy.ExecuteOnChannel(Uri endpointAddress, Action`1 action) at Microsoft.Office.ConversionServices.Service.ConversionServiceApplicationProxy.BatchGetSyncJobStatus(ICollection`1 ucids, Uri endpointAddress) at Microsoft.Office.ConversionServices.Service.BatchGetStatusPollingThread.Run() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() StackTrace: at onetnative.dll: (sig=37460b31-4453-4365-92f5-3a11c267be48|2|onetnative.pdb, offset=28F56) at onetnative.dll: (offset=15735) 

Now I’m at a loss how to get rid of the marker problem so that the system can create the necessary channel for polling the status of the conversion job. Any help is much appreciated. Thanks!

(I can not publish the full journal because it is registered as spam)

+5
source share
2 answers

Ive found that if you must install SharePoint 2013 on a domain controller (the topology that Microsoft says is good only for development, but not for production), then the default anonymous user in IIS (IUSR) will not work reliably, and any WCF solution accessed through an IIS site with anonymous access configured to use an IUSR account will not succeed when trying to access the security token service.

In this case, the most appropriate solution is to reconfigure IIS to use another anonymous identifier, namely the identifier associated with the application pool.

For example, if your site is called NameOfSite , you can run it in advanced PowerShell:

 Set-WebConfigurationProperty ` -Filter /system.WebServer/security/authentication/AnonymousAuthentication ` -Name username ` -Value "" ` -location "NameOfSite" 

This solves the immediate problem, which is that SecurityTokenForServiceContext fails. However, if you installed SharePoint 2013 on Windows 2012 R2 as a domain controller, then this is not the end: WordServerWorker does not actually start in this configuration.

However, I can also confirm that if you have to install SharePoint 2013 on a stand-alone server (with the role <Setting Id="SERVERROLE" Value="SINGLESERVER"/> in the unattended file), then the whole solution will work end-to-end, and WordServerWorker will actually start right.

Previously, the most relevant (and unanswered) question on this should have been the publication of MSDN, the request for the security token could not be completed ., I would assume that in this case the service was only in a metastable state, and one of the IIS employees previously received credentials through NTLM during local testing.

+4
source

Typically, when sharepoint service applications interact with each other, these services maintain the current user context through wcf calls using the service application infrastructure (SAF). It allows these services to use SPContext.Current , to store the correlation identifier between calls in logs, and so on. When this context is lost, services stop communicating with each other. For example, this happens if we have code that starts a new thread but does not configure the user for the newly created thread context.

According to your description, your service is anonymous and does not use SAF to support the user context, but uses some services that require the existence of this context.

A possible solution would be to use SAF (which is a complex WCF configuration in a nutshell) instead of regular WCF services without authentication

Edit:

Another possible solution would be to wrap your code with RunWithElevatedPrivileges so that your services connect a common point with the application pool identifier

0
source

All Articles