Connecting WCF from Webpart - c#

I am consuming a WCF Service from a webpart in Sharepoint 2007. But its giving me the following error:
There was no endpoint listening at
http://locathost:2929/BusinessObjectService
that could accept the message. This is
often caused by an incorrect address
or SOAP action. See InnerException, if
present, for more details. --->
System.Net.WebException: The remote
server returned an error: (404) Not
Found.
My Binding Details in the WCF web.config is:
<system.serviceModel>
<diagnostics performanceCounters="All">
<messageLogging logEntireMessage="true" logMessagesAtServiceLevel="false"
maxMessagesToLog="4000" />
</diagnostics>
<services>
<service behaviorConfiguration="MyService.IBusinessObjectServiceContractBehavior"
name="MyService.BusinessObjectService">
<endpoint address="http://localhost:2929/BusinessObjectService.svc"
binding="wsHttpBinding" contract="MyService.IBusinessObjectServiceContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyService.IBusinessObjectServiceContractBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
My binding details in the Sharepoint site web.config is:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IBusinessObjectServiceContract"
closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false"
hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" messageEncoding="Mtom" textEncoding="utf-8"
useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:2929/BusinessObjectService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IBusinessObjectServiceContract"
contract="BusinessObjectService.IBusinessObjectServiceContract"
name="WSHttpBinding_IBusinessObjectServiceContract">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
I am able to view the WCF (and its wsdl) in browser, using the URL given in the end point. So, I guess the URL is definately correct. Please help !!!

I've replicated your code and it runs correctly for me, but there are a couple of discrepencies.
Firstly, the server side configuration you've supplied is not complete. The endpoint mex fails because I don't have the IMetadataExchange contract. When you browse to the WSDL, this is presumably the endpoint you are viewing.
I'm just removing this endpoint altogether. Following from this, I'm specifying an address for the serviceMetadata element in the behavior like this:
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:2929/BusinessObjectService.svc?wsdl" />
Not ideal but it works to let me discover the service. Then my generated client config file is the same as yours, except...
Secondly, I have messageEncoding="Text" instead of messageEncoding="Mtom"
Try changing messagingEncoding to Text. You haven't specified on server side that it should be Mtom so I don't understand why it has been generated on client side as Mtom.
Apart from these two issues my configuration is the same as yours, and it runs without a problem. I'm not sure that the second issue I've identified is a real issue at all (I can't see how the metadata exchange would give the wrong message encoding), but the first issue is stopping the service from running on my side.

I got an error that looked almost identical as the described error. However my error was a 503 and I was calling a web service on an external server.
When I called the service from a standalone app I had no problems, but when I called the service from a web part in SharePoint it failed.
Solutions that worked me, without any further explanation because I haven't really digged into why it works (If you know, please enlighten me :))
1st solution that worked for me was to use my own domain account instead of the service account for the application pool that was used by the SPWebApplication.
2nd solution was to set the service binding attribute UseDefaultWebProxy to false
UseDefaultWebProxy = false
Of course these solutions depends on your proxy settings and user settings. My proxy settings was setup to bypass proxy for the service I was calling, so my suspicion is that the proxy settings (configured here: IE->Internet Options->Connections->LAN settings) doesn't apply to the service account but only to the logged in user. By now, this is what I'll investigate more.
EDIT 1:
Hmm. that was actually not bringing anything new to the table, I used psexec to view my proxy settings as the service account (netsh->winhttp->show proxy) and that looked correct, so I don't think this could be the issue.
EDIT 2:
Final solution, so the problem was that my SP web app was not using the proxy settings I had setup in IE when the app pool was run in the context of a service account, when I used my user account for the app pool I had no problems and the proxy settings in IE was used. After a little more investigation it appeared that I could define proxy settings for my SPWebApplication in web.config and I chose just to disable the proxy
<system.net>
<defaultProxy enabled="false" />
</system.net>

Related

Could not find a base address that matches scheme net.tcp for the endpoint with binding NetTcpBinding. Base address schemes are [http]

I have this configuration for my WCF service which runs on IIS Express port number 50187. The service is hosted on IIS Express of Visual Studio 2017:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="QCConsumerBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="50000000" maxBufferPoolSize="5242880" maxReceivedMessageSize="50000000" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="QCWCFService.QCService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="QCConsumerBinding" contract="QCWCFService.IQCService" />
</service>
<service name="QCWCFService.QCFinalService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="QCConsumerBinding" contract="QCWCFService.IQCFinalService" />
</service>
<service name="QCWCFService.CalibrationService">
<endpoint address="service" binding="netTcpBinding" contract="QCWCFService.ICalibrationService" />
<endpoint address="" binding="wsDualHttpBinding" contract="QCWCFService.ICalibrationService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8080/CalibrationService" />
<add baseAddress="http://localhost:8081/CalibrationService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="wsDualHttpBinding" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
But when I try to run the service it gives this exception:
System.InvalidOperationException: Could not find a base address that matches scheme net.tcp for the endpoint with binding NetTcpBinding. Registered base address schemes are [http].
While I have another application with the same configuration for Dual Http Binding which works perfectly
By default, The IIS express doesn’t support Net.tcp protocol.
The service endpoint with Nettcpbinding requires a base address based on NetTcp protocol.
<endpoint address="service" binding="netTcpBinding" contract="QCWCFService.ICalibrationService" />
Although we provide a Nettcp base address by using the Host Section, It won’t work. This is due to the fact IIS express use self-configuration to provide a base address to run the current project. The configuration of IIS express usually located in the .vs folder of the current Solution, called applicationhost.config
If we run this project in a console application with this configuration, it will work. Thereby we should provide one base address with Nettcp protocol. This can be completed in IIS.
1. Enable windows feature for net.tcp protocol.
2. Add Net.tcp support on the website.
3. Add net.tcp protocol in site binding module.
Please refer to the below for details of adding net.tcp protocol to a website.
WCF ContractFilter Mismatch when enabling Reliable Session
Feel free to let me know if the problem still exists.

What is wrong with my Silverlight / WCF Configuration

I've been struggling for a few hours I admit. I must be missing something with the Bindings/Configuration between my Silverlight application and WCF web service. It was working for awhile, but I must have accidentally changed some settings and I can't get it to work anymore.
In Visual Studio when I debug I have both the Service and Silverlight application launch at the same time, I have Windows authentication disabled in the web.config files for debugging. When I deploy, I go back and change my Configuration files to enable Windows security/transport so I can get user credentials on the web service side.
Now when I deploy both the WCF service and the Silverlight application to a different machine using IIS, I get an error "Not Found" from Silverlight when it attempts to contact the WCF service. Could someone explain to me the different configuration files that exist and what each should be pointing to? Here are my configuration files in their respective locations:
wwwroot\webserviceapp\web.config
<?xml version="1.0" encoding="UTF-8"?>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="WebserviceName.Service1">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="BasicHttpEndpointBinding"
name="BasicHttpEndpoint" contract="WebserviceName.IService1">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
wwwroot\web.config - this is the web.config for silverlight I guess?
<?xml version="1.0" encoding="UTF-8"?>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://<<<ip_to_machine>>>/webserviceapp/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpEndpoint"
contract="ServiceReference1.IService1"
name="BasicHttpEndpoint" />
</client>
</system.serviceModel>
<system.webServer>
<defaultDocument>
<files>
<add value="ProjectTestPage.html" />
</files>
</defaultDocument>
</system.webServer>
wwwwroot\ClientBin\SilverlightApp.xap (the ServiceReferences.ClientConfig file):
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpoint" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="TransportCredentialOnly" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://<<<ip_to_machine>>>/webserviceapp/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpEndpoint"
contract="ServiceReference1.IService1"
name="BasicHttpEndpoint" />
</client>
</system.serviceModel>
These are the three configuration files which seem to drive everything, unless I am wrong? Since I develop on one environment and deploy to another it seems like I must change these files to point to the right resources. When I hit my Silverlight application after I've deployed it to the new machine I get the application loading. Once it finishes loading, the first web service call it makes fails with exception and I get this in the Chrome Console:
Failed to load resource: the server responded with a status of 500 (Internal Server Error) http://<<<ip_to_machine>>>/webserviceapp/Service1.svc
Failed to load resource: the server responded with a status of 500 (Internal Server Error) http://<<<ip_to_machine>>>/webserviceapp/Service1.svc
Uncaught Error: Unhandled Error in Silverlight Application An exception occurred during the operation, making the result invalid. Check InnerException for exception details. at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at Project.ServiceReference1.GetAllNewsCompletedEventArgs.get_Result()
at Project.View.Home1.ClientGetAllNewsCompleted(Object pSender, GetAllNewsCompletedEventArgs pEventArgs)
at Project.ServiceReference1.Service1Client.OnGetAllNewsCompleted(Object state)
I'm like 99% certain that the Service is NEVER hit. I have a log statement at the very top of the function which is being called and it never logs anything.
IIS Configuration:
Web Service Authentication:
Anonymous = Disabled
ASP.NET Impersonation = Disabled
Windows Authentication = Enabled
Default Web Site (where my silverlight app is hosted):
Anonymous = Disabled
ASP.NET Impersonation = Disabled
Windows Authentication = Enabled
Anyone have any suggestions, or need anymore information from me to help debug?
EDIT: It is worth noting that I am able to navigate to the service from a different machine and see the service wsdl just fine. For example:
http://ipaddress/webserviceapp/Service1.svc
I can see this just fine, no errors.
I think the answer is pretty simple. The error I was receiving is a very generic error. The proper thing to do in this instance is to use Fiddler which will tell you EXACTLY what the error is. In my case, Trace logging wasn't working properly due to the service not loading properly. However, Fiddler was able to give me the exact exception messages which led me to resolve the problem quickly and easily.

WCF exception while connecting

I have added WPF Application to WCF Class library and my App config in WCF is as follows
<service name="WCFChatApplication.Service1">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8732/Design_Time_Addresses/WCFChatApplication/Service1/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address ="" binding="wsDualHttpBinding" contract="WCFChatApplication.IMessageServiceInbound">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
and my WPF app cpnfig is
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IMessageServiceInbound" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" />
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsDualHttpBinding>
</bindings>
But when I call
ServiceReference1.MessageServiceInboundClient Sc1 = new ServiceReference1.MessageServiceInboundClient(new InstanceContext(this),"WSDualHttpBinding_IMessageServiceInbound");
Sc1.Open();
The error I get is
HTTP could not register URLhttp://+:80/Temporary_Listen_Addresses/9b1e11c2-0c91-43a6-9a17-26f473a9fdbc/ because TCP port 80 is being used by another application.
The process using port 80 is Inetinfo.exe.I cant seem to close this process.
Is there a way I can move from port 80 to any other port.
Thanks
You're using a duplex binding, so the client has to set up an address where the server can reach it. By default it seems to use port 80, which is in use by IIS.
Set the clientBaseAddress of the binding to another address and you should be good to go. Make sure the port is accessible on the client from the server (firewall, port forwarding et al).
My guess is that Visual Studio is trying to host the WCF service and this causes a conflict with the hosting done by your application.
Open the properties of the WCF project.
Open the WCF options tab.
Uncheck the first checkbox (Start WCF Service Host when debugging another project in the same solution)
Close Skype. Booya. Had the same issue. Think you can change your skype ports.
http://forums.iis.net/t/1086489.aspx?IIS+Manager+Error+The+process+cannot+access+the+file+because+it+is+being+used+by+another+process+Exception+from+HRESULT+0x80070020+

The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'NTLM'

Few days ago I had quite a headache with authentication problems when using Windows authentication between client and wcf web service. The error I was getting was "The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was "NTLM". None of the solutions on stack worked because most of them were related to old methods.
THE ANSWER: The problem was all of the posts for such an issue were related to older kerberos and IIS issues where proxy credentials or AllowNTLM properties were helping. My case was different. What I have discovered after hours of picking worms from the ground was that somewhat IIS installation did not include Negotiate provider under IIS Windows authentication providers list. So I had to add it and move up. My WCF service started to authenticate as expected. Here is the screenshot how it should look if you are using Windows authentication with Anonymous auth OFF.
You need to right click on Windows authentication and choose providers menu item.
Hope this helps to save some time.
I have upgraded my older version of WCF to WCF 4 with below changes, hope you can also make the similar changes.
1. Web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="Demo_BasicHttp">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="InheritedFromHost"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="DemoServices.CalculatorService.ServiceImplementation.CalculatorService" behaviorConfiguration="Demo_ServiceBehavior">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="Demo_BasicHttp" contract="DemoServices.CalculatorService.ServiceContracts.ICalculatorServiceContract">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Demo_ServiceBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="basicHttpBinding" bindingConfiguration="Demo_BasicHttp"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
2. App.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ICalculatorServiceContract" maxBufferSize="2147483647" maxBufferPoolSize="33554432" maxReceivedMessageSize="2147483647" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="00:10:00">
<readerQuotas maxArrayLength="2147483647" maxBytesPerRead="4096" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:24357/CalculatorService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICalculatorServiceContract" contract="ICalculatorServiceContract" name="Demo_BasicHttp" />
</client>
</system.serviceModel>
Not this exact problem, but this is the top result when googling for almost the exact same error:
If you see this problem calling a WCF Service hosted on the same machine, you may need to populate the BackConnectionHostNames registry key
In regedit, locate and then click the following registry subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
Right-click MSV1_0, point to New, and then click Multi-String Value.
In the Name column, type BackConnectionHostNames, and then press ENTER.
Right-click BackConnectionHostNames, and then click Modify.
In the Value data box, type the CNAME or the DNS alias, that is used for the local shares on the computer, and then click OK.
Type each host name on a separate line.
See Calling WCF service hosted in IIS on the same machine as client throws authentication error for details.
For me the solution was besides using "Ntlm" as credential type:
XxxSoapClient xxxClient = new XxxSoapClient();
ApplyCredentials(userName, password, xxxClient.ClientCredentials);
private static void ApplyCredentials(string userName, string password, ClientCredentials clientCredentials)
{
clientCredentials.UserName.UserName = userName;
clientCredentials.UserName.Password = password;
clientCredentials.Windows.ClientCredential.UserName = userName;
clientCredentials.Windows.ClientCredential.Password = password;
clientCredentials.Windows.AllowNtlm = true;
clientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
}
The solution for me was to set the AppPool from using the AppPoolIdentity to the NetworkService identity.
I had the same problem, to solve it set specific user from domain in iis -> action sidebar->Basic Settings -> Connect as... -> specific user

Sporadic exceptions calling a web service that is load balanced

I have a web service that I am running on three load balanced web servers and I am getting sporadic errors. Now, I admit that the load balanced part may be a bit of a red herring, but when I test with only 1 web server I cannot reproduce the error. If I test with all three web servers I can get the error (but it is not 100% of the time, more like 50%). All testing is done through the load balancer, we just tell the load balancer how many servers we want to farm.
The code is simple single request code. That is, there is no state. A request is made and a response is returned. The web service code is c# .NET 4 running on IIS 7.5. The client code is both a web site and a desktop app.
I get one of two exceptions:
System.ServiceModel.Security.MessageSecurityException:
An unsecured or incorrectly secured
fault was received from the other
party. See the inner FaultException
for the fault code and detail. --->
System.ServiceModel.FaultException:
The security context token is expired
or is not valid. The message was not
processed.
Or I get:
System.ServiceModel.Security.SecurityNegotiationException:
Secure channel cannot be opened
because security negotiation with the
remote endpoint has failed. This may
be due to absent or incorrectly
specified EndpointIdentity in the
EndpointAddress used to create the
channel. Please verify the
EndpointIdentity specified or implied
by the EndpointAddress correctly
identifies the remote endpoint. --->
System.ServiceModel.FaultException:
The request for security token has
invalid or malformed elements.
As you can see from the following snips from my .config files, I am not using security as this is strictly an internal web service. (names have been changed to protect the innocent--namely me).
Server Side:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Service Side web.config -->
...
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="InternalUseOnly.InternalUseOnlyServiceBehavior" name="InternalUseOnly.InternalUseOnlyService">
<endpoint address="" bindingNamespace="http://somecompany.com/webservices" binding="wsHttpBinding" contract="InternalUseOnly.IInternalUseOnlyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="InternalUseOnly.InternalUseOnlyServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
...
</configuration>
Client side
<?xml version="1.0" encoding="UTF-8"?>
<!-- Client Side web.config -->
<configuration>
...
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IInternalUseOnlyService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://intranet.somecompany.com/InternalUseOnly/InternalUseOnlyService.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IInternalUseOnlyService" contract="InternalUseOnlyService.IInternalUseOnlyService" name="WSHttpBinding_IInternalUseOnlyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
...
</configuration>
Thoughts anyone?
Additional information: After reviewing the answers below I have tried two things, both without success.
The most obvious change (which I did not notice at first) was to change one of properties on the client to allow cookies <system.serviceModel><bindings><wsHttpBinding><binding name="blah, blah, blah" ... other properties... allowCookies="true" /> It defaults to false. Further, our load balancer uses cookies to keep affinity. But, it did not make a difference (no clue why yet).
Next, I tried various security options in the client side app.config file. This included both <security mode="None" /> and a more elaborate:
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" />
<message clientCredentialType="None" establishSecurityContext="false" negotiateServiceCredential="false"/>
</security>
although the settings in the last one was just a guess on my part. I did not make any server side changes to the app.config as I don't know what to change and, sadly, I can only test with production as we only have 1 dev web server, not three.
I am going to go out on a limb here and guess that the security involved is the Message security specified on the client side:
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" />
</security>
If you are creating a client and connecting, the negotiated windows credential token may be cached. If you don't have sticky sessions enabled, the token might be passed back to the wrong server and will fail. My guess is that its always on the second call?
It is an NTLM problem caused by using load balancers without sticky sessions. To correct the problem you need to configure session affinity (sticky session). If you don't you will get a failure because part of the NTLM handshake happened on one server and the other part happens on another server.
While Chris and Jeff have help get me on the track to an answer, what actually solved it for me was this article i found from Microsoft on Load Balancing Web Services. In short, what we had to do to resolve this for our web farm was to switch from the default wsHttpBinding to basicHttpBinding. This was not difficult, but was an all-or-nothing move. The main web service and every client had to be reconfigured at the same time or it would break.
While wsHttpBinding does have a property of allowCooikes that could be set to true, it apparently does not use them until after the connection is made, at which point the request could jump servers on the first request and thus fail.

Categories

Resources