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.
Related
I have a website which connects to a WCF service deployed in IIS on two application servers behind a load balancer & firewall. When I use HTTP endpoints the website is able to connect to the WCF service successfully. However on switching to TCP protocol, I am seeing the following error.
More data was expected, but EOF was reached.
[InvalidDataException: More data was expected, but EOF was reached.]
[ProtocolException: Error while reading message framing format at position 0 of stream (state: ReadingUpgradeRecord)]
[ProtocolException: The server at net.tcp:///SecurityService.svc rejected the session-establishment request.]
The website application pool is running under a local user account, while the WCF services are running under default ApplicationPoolIdentity. No trace logs are getting generated at the service end. Trace logs are getting generated at the client end with the same error.
The WCF service is hosted under the default port 808 in the application server, but it is not being shared by any other application/service.
Environment: Win2k8, IIS 7.5
I have verified the TCP connectivity to the application server from the web server and it is fine.
Please let me know if any other information is needed from my side. Really appreciate any guidance as I have spent a lot of time on this.
The snippet from the config files are below:
WCF Service
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_Configuration" closeTimeout="00:10:00"
openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
maxBufferSize="2147483647" maxConnections="100" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="<namespace>.ServiceImplementation.Security">
<endpoint address="net.tcp://<servername>/SecurityService.svc"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_Configuration"
contract="<namespace>.ServiceInterface.ServiceContracts.ISecurity" name="NetTcpBinding_Security">
<identity>
<servicePrincipalName value="host/<servername>" />
</identity>
</endpoint>
</service>
</services>
Website Client
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_Configuration" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" 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>
</basicHttpBinding>
<netTcpBinding>
<binding name="NetTcpBinding_Configuration" 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="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="http://<servername>/SecurityService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_Configuration" contract="SecurityService.Security" name="BasicHttpBinding_Security" />
<endpoint address="net.tcp://<servername>/SecurityService.svc" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_Configuration" contract="SecurityService.Security" name="NetTcpBinding_Security">
<identity>
<servicePrincipalName value="host/<servername>" />
</identity>
</endpoint>
</client>
If I was you, I would Wireshark the traffic going from the client to the server. You just want to make sure that your traffic is not getting blocked somewhere along the way. If you can confirm that this is NOT the case, then it has to be a WCF service configuration issue.
Before you attempt to debug WCF config, try to remove the load balancer out of the picture(if you can), and hit the WCF service directly. Most of the load balancers will support HTTP by default; but will need special configuration for any other protocols.
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.
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.
I'm using WCF to connect to a remote web service (asmx) for testing at this point. The remote web service is unsecured for now (no https, no user name, password). I can add the WCF service reference, and all the classes are generated ok. When I make the call to the webservice, it just hangs.
So I can connect with the SOAP UI tool and return data just fine. I'm thinking it is something wrong with my binding. Anyone see anything I'm missing?
<system.serviceModel>
<bindings>
<!-- Need to change some settings here for HTTPS and Basic Auth when those go online-->
<basicHttpBinding>
<binding name="ServiceSoap" 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>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://<snip>/Service.asmx"
binding="basicHttpBinding" bindingConfiguration="ServiceSoap"
contract="PRIOrderService.ServiceSoap" name="ServiceSoap" />
</client>
</system.serviceModel>
Requesting the wsdl endpoint does not trigger a creation of the instance of your service. If you are using a custom service host factory look at that, otherwise look at the constructor of your service implementation or debug the service method itself.
We have a client that has been configured to connect to an asmx service. We don't want to ask our customers to update their configuration, but we would like to upgrade our service to use WCF. Does anyone know if WCF supports this? If so, what would the configuration file look like?
Our asmx service looks like this:
<bindings>
<binding name="ATransactionSoap" 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>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://.../atransaction.asmx" binding="basicHttpBinding" bindingConfiguration="ATransactionSoap" contract="ATransactionSoap" name="ATransactionSoap" />
In response to your follow-up question:
any way to use WCF without changing the URL of the service?
Yes, you can make the old .asmx url re-direct to your .svc url. It requires configuration changes on the service side as well as a change to your .asmx file. But your existing client can continue to connect unchanged in any way. See http://kaushikrabadiya.blogspot.com/2008/11/how-to-use-asmx-extension-to-handle-wcf.html.
Your client won't have to change, except to change the URL of the service.