In the pas 48 hours, I was struggling with the problem in our SharePoint Farm. The problem, all SharePoint Web Services were not working. If one tries to visit standard web service such as SecurityTokenServiceApplication (http://localhost:32843/SecurityTokenServiceApplication/SecurityToken.svc , or https://localhost:32844/SecurityTokenServiceApplication/SecurityToken.svc ), the service will respond with System.InvalidOperationException (see picture):
An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: System.InvalidOperationException: An exception was thrown in a call to a policy export extension. Extension: System.ServiceModel.Channels.TransportSecurityBindingElement Error: Security policy export failed. The binding contains a TransportSecurityBindingElement but no transport binding element that implements ITransportTokenAssertionProvider. Policy export for such a binding is not supported. Make sure the transport binding element in the binding implements the ITransportTokenAssertionProvider interface. ----> System.InvalidOperationException: Security policy export failed. The binding contains a TransportSecurityBindingElement but no transport binding element that implements ITransportTokenAssertionProvider. Policy export for such a binding is not supported. Make sure the transport binding element in the binding implements the ITransportTokenAssertionProvider interface. at System.ServiceModel.Channels.TransportSecurityBindingElement.System.ServiceModel.Description.IPolicyExportExtension.ExportPolicy(MetadataExporter exporter, PolicyConversionContext policyContext) at System.ServiceModel.Description.MetadataExporter.ExportPolicy(ServiceEndpoint endpoint) --- End of inner ExceptionDetail stack trace --- at System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata() at System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized() at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.InitializationData.InitializeFrom(ServiceMetadataExtension extension) at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.GetInitData() at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.TryHandleDocumentationRequest(Message httpGetRequest, String queries, Message& replyMessage) at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.ProcessHttpRequest(Message httpGetRequest) at SyncInvokeGet(Object , Object , Object ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object inputs, Object& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
What does the page tell us?
It tells that binding contains TransportSecurityBindingElement but the framework can not find transport binding element that implements ITransportTokenAssertionProvider. I still have no idea why, previously the security policy export allowed it – but not anymore. ( I wish I will dig more, but at the moment our focus is to find the correct configuration so that it complies with security policy export rule.)
Let’s dig into the configuration
Take SecurityTokenService binding in web.config as an example (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\WebServices\SecurityToken\web.config).
There are 3 bindings, with either httpsTransport or httpTransport:
- spStsBinding , with httpTransport
- spStsActAsBinding, with httpsTransport
- SPWindowsTokenCacheServiceHttpsBinding, with httpsTransport
If we check MSDN Documentation about interface ITransportTokenAssertionProvider , we know that it expose GetTransportTokenAssertion method to the class. Comparing HttpsTransportBindingElement class which handles httpsTransport operation ; and HttpTransportBindingElement class which handles httpTransport operation; we know that the second (HttpTransportBindingElement) does not have GetTransportTokenAssertion method.
Yes, the issue lays on httpTransport, which means that we have to change httpTransport to httpsTransport.
If we change to httpsTransport, then all http communication will not work – so the second task is to find how to allow unsecured communication through https binding. Searching to hotfixes to .NET Framework, I can find this KB971493 (FIX: A hotfix that enables WCF to send secured messages and to receive unsecured responses, and to send unsecured messages and to receive secured responses, is available for the .NET Framework 3.5 SP1) . So, the next is to enableUnsecuredResponse=”true” in the binding security.
The final web.config of the SecurityTokenService is,
Summary, what you need todo
- Change all
httpTransportbinding to httpsTransport binding.
- Add allowInsecureTransport=”true” and enableUnsecuredResponse=”true” to the binding security.
- Ensure that you define only 1 binding configuration ( for example in Profile Service, we will find 2 binding configuration for the same service each for http and https protocol).