Claims Authentication and The Secure Store Service application Secure Store Service is not accessible

26/06/2014

Working with Business Data Connectivity Service in SharePoint have always been a bit of an authorization nightmare, as there is quite a few ways to do it. Today we had an interesting issue at work in our upgraded SharePoint 2013 Farm. The application that was having issues connecting to BDC consists of the following components.
bdcsetup

As you can see from the diagram the setup was quite complex, the reason for this elaborate setup was that the solution was built by another contractor that was not allowed to build farm solutions. So they came up with the idea of making external lists of the data that they needed and then connect to the lists from the Sandbox solution to read the data and present it in a nicer way than possible with the standard BDC webparts.

Despite the complexity of the setup, it has been working fine until we decided to upgrade the web application to windows claims authentication instead of the classic authentication. Now the sandbox code could no longer read data from the external list, it failed with the following exception: The Secure Store Service application Secure Store Service is not accessible.
Looking more closely at the ULS the more detail description was (I removed some of the very lengthy stack trace):

Logging unknown/unexpected client side exception: CommunicationException. This will cause this application server to be removed from the load balancer queue. Exception: System.ServiceModel.CommunicationException: An error occurred while receiving the HTTP response to https://:32844/dc5ac747aa7f4600b32dab7bb38974b8/SecureStoreService.svc/https. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.SharePoint.Utilities.SPThreadContext.get_UserCodeContext() at Microsoft.SharePoint.Utilities.SPThreadContext.get_Items() at Microsoft.SharePoint.CoordinatedStreamBuffer.SPCoordinatedStreamBufferFactory.RecordMemoryAllocation(Int64 size) at Microsoft.SharePoint.Utilities.SPChunkedArrayList`1..ctor(Int32 size) at Microsoft.SharePoint.Utilities.SPSqlCommand..ctor() at Microsoft.SharePoint.SPStoredProceduresConfig.proc_getObjectsByClass(Nullable`1 ClassId, Nullable`1 ParentId, String Name) at Microsoft.SharePoint.Administration.SPConfigurationDatabase.FetchId(QualifiedObjectName qName) at Microsoft.SharePoint.Administration.SPConfigurationDatabase.GetObject(String name, Guid parentId, Type type) at Microsoft.SharePoint.Administration.SPTrustedRootAuthorityManager.GetLocal(SPFarm farm) at Microsoft.SharePoint.SPCertificateValidator.CreateImmutableValidator() at Microsoft.SharePoint.SPCertificateValidator.Validate(X509Certificate2 certificate) at Microsoft.SharePoint.SPCertificateValidator.IsValid(X509Certificate2 certificate) at Microsoft.SharePoint.SPCertificateValidator.ValidateRemoteServerCertificate(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) at System.Net.ServerCertValidationCallback.Callback(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx

The strange thing was that the external list was still working when opened directly in SharePoint, so obviously the issue was limited to the SPUCWorkerProcessProxy.exe process that runs the sandbox code.

Originally, the authentication mode used for connecting the external system was impersonation and the user credentials for impersonation was stored in a secure store application. I was not been able to pin-point what made the user code worker process fail to connect to the Secure Storage Application when the web-application was using claims authentication, but I found a way solve the problem.

The solution for us (despite the lower level of security) was to allow BDC to revert to self, which means that BDC will be able to authenticate with external systems as the app pool account. This is a security risk as designers are then able to create BCS models that can connect as the application pool account, but if you trust your designers it should be okay.

To enable BDC to revert to self, or use BDC Identity as it’s called in the BDC userinterface (see this article for a good clarification of the naming confusion: http://blogs.msdn.com/b/bcs/archive/2010/03/12/authenticating-to-your-external-system.aspx) you have to run the following PowerShell script:

$bdc = get-spserviceapplication |? {$_.GetType().FullName -eq "Microsoft.SharePoint.BusinessData.SharedService.BdcServiceApplication"}

$bdc.RevertToSelfAllowed = $true
$bdc.Update()

When you have done that you will be able to select the Authentication mode “BDC Identity” in the configuration for your External System, and your connectivity issues will disappear.
BDCIdentity