Problems with WCF reliable session (reliable messaging) - wcf

In our WCF application I am trying to configure reliable sessions.
Service:
<wsHttpBinding>
<binding name="BindingStabiHTTP" maxBufferPoolSize="524288"
maxReceivedMessageSize="2097152"
messageEncoding="Text">
<reliableSession enabled="true" ordered="true"
inactivityTimeout="00:10:00"/>
<readerQuotas maxDepth="0" maxStringContentLength="0"
maxArrayLength="0" maxBytesPerRead="0"
maxNameTableCharCount="0" />
</binding>
</wsHttpBinding>
Client:
<wsHttpBinding>
<binding name="BindingClientWsHttpStandard" 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="true" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows"
negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
Unfortunately I get an error which is as follows:
No signature message parts were specified for messages with the 'http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence' action.
If I disable the reliableSession on the client I get this message:
The action is not supported by this endpoint. Only WS-ReliableMessaging February 2005 messages are processed by this endpoint.
So it seems that the server is configured correctly for RM.
I cannot find anything valuable about the error I get so I don't know how to fix this. Any ideas what can be wrong?
Thank in advance,
Rob

After starting a new test project that worked fine with RM I finally found the problem by comparing the configuration files. It appeared that our service configuration did not specify the correct binding configuration:
<service behaviorConfiguration="somebehavior"
name="somename">
<endpoint address="" binding="wsHttpBinding"
bindingConfiguration="SomeBinding"
name="http"
contract="somecontract" />
<endpoint address="mex"
binding="mexHttpBinding"
bindingConfiguration=""
name="mex"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/Design_Time_Addresses/somelibrary/someservice/" />
</baseAddresses>
</host>
</service>
This bindingConfiguration was empty. It then takes the default wsHttpBinding which is something different then the one specified (even if there is only 1).

I think the security settings for client and server don't match.
The client has:
<security mode="Message">
<transport clientCredentialType="Windows"
proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
and the server has nothing at all.....
Can you try to have the same settings for both client and server? Does it work then??

Related

WCF Binding Transport/Windows Binding Security Not Being Enforced

I'm in the process of adding SSL security with Windows authentication to a formerly unsecured IIS hosted WCF service application. To my surprise, I found that two of the service endpoints were already using a Binding with Transport and Windows security. This is confusing because the client applications consuming this service are not configured to use Transport security or Windows credentials. Here is the service config:
<binding name="LargeBuffer" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
...
<service behaviorConfiguration="WebServices.GCServiceBehavior"
name="WebServices.GCService">
<endpoint address="" binding="basicHttpBinding" name="GCSecuredEndpoint"
bindingName="largeBuffer" contract="WebServices.IGCService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
When I use Visual Studio to generate the client proxy and configuration, it creates this:
<binding name="GCSecuredEndpoint" 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="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
...
<endpoint address="http://devservices.mysite.com/GCService/GCService.svc"
binding="basicHttpBinding" bindingConfiguration="GCSecuredEndpoint"
contract="GCSvc.IGCService" name="GCSecuredEndpoint" />
Notice it's security mode="None" and Transport ClientCredentialType is None instead of Windows. When I call a method on the GCService it succeeds. I would expect it to first complain that I'm trying to access over http instead of https, but it doesn't. Next I would expect it to not authenticate or complain that the client endpoint doesn't match the service in terms of authentication, but it doesn't.
I have another service in the same application that I had just setup with Transport/Windows security just without all the buffer/readquota stuff. For starters, when I generate the client proxy/config in VS for this service, it automatically uses the https address, transport security, and windows authentication. If I manually change it to use None for both, as above, a call to one of the service methods does not succeed, as expected. Why is the GCService above working?
The server config has
bindingName="largeBuffer"
instead of
bindingConfiguration="LargeBuffer"
The LargeBuffer binding configuration was never being used.

WCF configuration with https

I'm not having any success setting up HTTPS in my development environment on an existing WCF service. The service has been fine with http. I'm using the hosts file to redirect to localhost, which has been working for http.
My web service configuration
<services>
<service name="EnfieldWebService">
<endpoint address="https://enfieldwebservice.devserver.int/EnfieldWebService.svc"
binding="basicHttpBinding" bindingConfiguration="transportSecurity" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="transportSecurity">
<security mode="Transport">
</security>
</binding>
</basicHttpBinding>
</bindings>
Client configuration
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IEnfieldWebService" 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="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://enfieldwebservice.devserver.int/EnfieldWebService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IEnfieldWebService"
contract="HttpsEnfieldService.IEnfieldWebService" name="BasicHttpBinding_IEnfieldWebService" />
</client>
And Unit Test Results:
System.ServiceModel.EndpointNotFoundException: There was no endpoint listening at
https://enfieldwebservice.devserver.int/EnfieldWebService.svc 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.
Used WCF Configuration Editor to rewrite essentially the same configuration. All that it removed was
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
Turns out this feature is only compatible with http, and breaks https.

WCF Message Security - PerCall

We have a website load balanced across two servers that calls into a WCF wsHttp service hosted on a single IIS7 application server.
Last week, the website was launched and we hit performance problems.
The system was built by an off-shore team but I was asked to investigate if I could help.
I loaded perfmon and used the asp.net counters to view current sessions. I could see that once this increased above about 25 then the website slowed greatly. It would continue to increase to approx 250 over the course of the following 10 minutes, it would then drop to 0 and performance of the site would be great.
This continued in a cycle - bad news!
The following day, the off-shore team informed me that they'd fixed the problem by tuning off security.
I have a theory that in disabling the security on the wsHttp binding WCF changed from creating an instance per session to a creating an instance per call - therefore allowing a far greater throughput of service requests. Is this a good theory?
I've built a simple model to test this, a couple of methods hosted in IIS and a simple client that generates multiple requests. This does seem to give the results I'd expected. Problem is, I'm struggling to find the correct perfmon counters to prove that fewer requests are queued and more concurrent instances created, when the secure binding is not used.
Could anyone please advise on the best perfmon counters to use?
OK, another day on this and a more questions!
In my test app, I now have 3 service classes with 3 different wsHttp bindings
No security
Message Security
Message security but with [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] set on the class
From within a loop of 40 on the client I start a new thread and call the service. When calling service 1, the service completes all requests within 1 second.
When calling service 2, the service completes all requests in 33 seconds.
When calling service 3, I'd expect it to be almost as quick as service 1 since I'd expect the service to instantiate a new service object for each of the 4 calls. However, it doesn't seem (I still don't have any meaningful perfmon counters!) to do this and total time to complete is also 33 seconds.
Here is the config from the service:
<?xml version="1.0"?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true" >
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\WCFTrace\InstancingDemo.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="SecPerCallBehaviour">
<serviceThrottling maxConcurrentSessions="1000"
maxConcurrentCalls="30"
maxConcurrentInstances="30"/>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<bindings>
<wsHttpBinding>
<binding name="BindingNoSec">
<security mode="None" />
</binding>
<binding name="BindingMessageSec">
<security mode="Message">
<message establishSecurityContext ="true"/>
</security>
</binding>
<binding name="BindingMessageSecPerCall" >
<security mode="Message">
<message establishSecurityContext ="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="ServiceInstancingDemo.Service1">
<endpoint address="~/Service1.svc"
binding="wsHttpBinding" bindingConfiguration="BindingNoSec"
name="NoSecurity" contract="ServiceInstancingDemo.IService1" />
</service>
<service name="ServiceInstancingDemo.Service2">
<endpoint address="~/Service2.svc"
binding="wsHttpBinding" bindingConfiguration="BindingMessageSec"
contract="ServiceInstancingDemo.IService2" />
</service>
<service name="ServiceInstancingDemo.Service3" behaviorConfiguration="SecPerCallBehaviour">
<endpoint address="~/Service3.svc"
binding="wsHttpBinding" bindingConfiguration="BindingMessageSecPerCall"
contract="ServiceInstancingDemo.IService3" />
</service>
</services>
</system.serviceModel>
</configuration>
And here's the config from the client:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService2" 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" establishSecurityContext="true" />
</security>
</binding>
<binding name="NoSecurity" 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="None">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" />
</security>
</binding>
<binding name="WSHttpBinding_IService3" 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://rb-t510/NGCInstancing/Service2.svc/~/Service2.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService2"
contract="NGCWithSec.IService2" name="WSHttpBinding_IService2">
<identity>
<servicePrincipalName value="host/RB-T510" />
</identity>
</endpoint>
<endpoint address="http://rb-t510/NGCInstancing/Service1.svc/~/Service1.svc"
binding="wsHttpBinding" bindingConfiguration="NoSecurity"
contract="NGC.IService1" name="NoSecurity" />
<endpoint address="http://localhost/NGCInstancing/Service3.svc/~/Service3.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService3"
contract="NGCSecPerCall.IService3" name="WSHttpBinding_IService3">
<identity>
<servicePrincipalName value="host/RB-T510" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
I guess that I'm missing a config setting? Or maybe mutiple calls using message security over wsHttp are always going to be very slow because the server object must be instantiated per session and only a single session is created for each client?
Many thanks
Rob.
The counters you want have to be explicitly enabled in your service:
<configuration>
<system.serviceModel>
<diagnostics performanceCounters="All" />
</system.serviceModel>
</configuration>
Obviously it can be more granular too. This is what you want to read: WCF Performance Counters
Update:
A better link: How to use performance counters to diagnose performance of WCF applications

Just another "An existing connection was forcibly closed by the remote host" issue

I'm trying to access a WCF service on a company network. I'm using the proxy and config file generated by svcutil. The code looks like this:
using (Client client = new Client())
{
client.Open();
client.DoStuff();
}
Client is the client class in the generated proxy code, meaning it's derived from System.ServiceModel.ClientBase and implements the Contract interface.
And the config file looks like this:
<configuration>
<system.serviceModel>
<client>
<endpoint address="net.tcp://Address"
binding="netTcpBinding"
bindingConfiguration="Config"
contract="Namespace.Contract"
name="name">
<identity>
<servicePrincipalName value="Host" />
</identity>
</endpoint>
</client>
<bindings>
<netTcpBinding>
<binding name="Config"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
transactionFlow="false"
transferMode="Buffered"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
listenBacklog="10"
maxBufferPoolSize="524288"
maxBufferSize="65536"
maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32"
maxStringContentLength="8192"
maxArrayLength="16384"
maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
<reliableSession ordered="true"
inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
I get the exception "An existing connection was forcibly closed by the remote host" every time the code reaches client.Open(). What really bothers is that when I try it from another computer, there's no exception. And on top of that, the config file used to have Transport security which was changed to None, and the computer where it works still has the old config file with
<security mode="Transport">
<transport clientCredentialType="Windows"
protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
whereas on the first machine and the server it's
<security mode="None">
<transport clientCredentialType="None" />
</security>
What can cause this? I've read numerous other questions here regarding this exception, but none seemed to resemble my issue.
SOLVED! I have set the security options in the wrong place.
The service was self hosted with ServiceHost, and the Security property wasn't set, so it defaulted to something else than None.
Check your Security settings for this project on your IIS (you are using IIS right?). I think it still says authentication type Windows.

Accessing wcf web service with powershell2

I'm trying to write a cmdlet that accesses one of my wcf webservices.
I've been looking at the new cmdlet : New-WebServiceProxy, but it only really seems capable of consuming ASMX webservices.
I've seen this article; which is focussed around Powershell v1.0
I'd rather use a better method (if one exists).
http://keithhill.spaces.live.com/blog/cns!5A8D2641E0963A97!645.entry
From my other .net apps that consume this webservice, here's the sort of configuration i use;
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IMyService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="819200" maxArrayLength="1638400" maxBytesPerRead="409600" maxNameTableCharCount="1638400" />
<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" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://myServer/MyService/MyService.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMyService" contract="MyService.IMyService" name="WSHttpBinding_IMyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Anyone wanna advise me?
Ultimately you are going to want to create a client side proxy object, compile that into a .NET assembly, create that proxy and program against it in PowerShell. New-WebServiceProxy was written to allow you to do that. I'm surprised that it would only work against ASMX services? Perhaps it isn't working for you because you don't have a MEX endpoint defined in your config file? See this article on how to create a MEX endpoint that will enable proxy generation for your web service.