How to enable HTTPS in WCF service - wcf

I have hosted my service on IIS.
Hosted service has applied SSL certificate and on browse of URL, it appears with HTTPS.
But, when i do consume this URL into client application (ASP.NET WEB Application) then, it allows to add https//domain/service.svc but, on client configuration, it appears the URL as http and not https. when do manual change then, it gives error as follow: The provided URI scheme 'https' is invalid; expected 'http'.
Below is the WCF service configuration (hosted on IIS):
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="customBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="basicBindingConfiguration" closeTimeout="00:05:00"
openTimeout="00:05:00" receiveTimeout="00:10:00" sendTimeout="00:05: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">
</security>
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" />
<services>
<service name="Administrator.OAP.CRMServices.CRMServices"
behaviorConfiguration="customBehavior">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="basicBindingConfiguration"
contract="Administrator.OAP.CRMServices.Contracts.ICRMServices" />
</service>
</services>
can any one please guide me what is the problem or changes require here to consume this service with HTTPS only ?

Your binding has this:
<security mode="None">
Which means your service is not expecting to use security of any kind. HTTPS is transport authentication, so you need to set:
<security mode="Transport">
The following link includes useful information about setting up transport security in WCF: http://msdn.microsoft.com/en-us/library/ms733043(v=vs.110).aspx

Related

WCF Error A SOAP 1.2 message is not valid when sent to a SOAP 1.1 only using wsHttpBinding

I am trying to consume a service which I have no control over and have been given just the WSDL to consume. The service requires a certificate for authentication. My configuration for the certificate is fine and I get an error when I try and call the service as below:
The content type text/xml;charset=UTF-8 of the response message does
not match the content type of the binding (application/soap+xml;
charset=utf-8). If using a custom encoder, be sure that the
IsContentTypeSupported method is implemented properly. The first 274
bytes of the response were: 'soap:VersionMismatchA SOAP 1.2 message is not valid when sent to a SOAP 1.1 only
endpoint.'.
I have tried different this like using a customBinding but I landed up with a total new number of more errors and feel am not getting anyway. Can you please assist?
Client Config:
<system.serviceModel>
<client>
<endpoint name="IDeliveryServiceImplPort"
address="WebServiceUrl"
binding="wsHttpBinding"
bindingConfiguration="wsHttpBinding"
behaviorConfiguration="wsHttpCertificateBehavior"
contract="IDeliveryService">
<identity>
<dns value="MyIdentity" />
</identity>
</endpoint>
</client>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding" 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 enabled="false" ordered="true" inactivityTimeout="00:10:00" />
<security mode="Transport">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
<customBinding>
<binding name="WsHttpSoap11" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00">
<textMessageEncoding messageVersion="Soap11WSAddressing10" />
<security authenticationMode="MutualCertificate" />
<httpsTransport requireClientCertificate="true" />
</binding>
</customBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="wsHttpCertificateBehavior">
<clientCredentials>
<clientCertificate x509FindType="FindBySubjectName" findValue="MyIdentity" storeLocation="LocalMachine" storeName="My" />
<serviceCertificate>
<defaultCertificate x509FindType="FindBySubjectName" findValue="MyIdentity" storeLocation="LocalMachine" storeName="My" />
<authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck" trustedStoreLocation="LocalMachine" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
I have managed to figure it out with tweaks and trials. In order to solve is I change to basicHttpsBinding which took me another day or two to figure out the default transport clientCredentialType is None and you need to configure a custom binding as below. I wish WCF would tell you why or give a solution to error you get, because it was such a pain. From one error description to the next nonstop.
<bindings>
<basicHttpsBinding>
<binding name="SecureHubBinding">
<security>
<transport clientCredentialType="Certificate" />
<message clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpsBinding>
</bindings>
Are these configurations automatically generated by adding service reference? We can use the WSDL file of the service to generate the binding information used by the server-side and add the service reference to generate the client proxy class.
In addition, if the service with transport security mode authenticates the client with a certificate, please guarantee that below requirements.
The trusted relationship between the client-side and the server-side
should be established. Install mutual certificates in the Local CA.
These two certificates should be accessed by the WCF application.
Please add the Everyone account (or the account running the WCF
application) to the management group of the certificate private key.
Both two certificates should have the client authentication intended
purpose and the server authentication intended purpose.
Feel free to let me know if there is anything I can help with.

WCF: tcp service timeout when I transfer a file

I have a WCF service, that use tcp for the communication. When I try to transfer a file from the client to the service, if I do that in the same computerm in which the configure file in the client and in the service use the localhost for the url, I have not any problem.
However, if I try to do the same when the client is in other computer in the lan, I get the following exception:
System.TimeoutException: This request operation sent to net.tcp://192.168.1.5:7997/CMMSHost did not receive a reply within the configured timeout (00:01:00). The time allotted to this operation may have been a portion of a longer timeout. This may be because the service is still processing the operation or because the service was unable to send a reply message. Please consider increasing the operation timeout (by casting the channel/proxy to IContextChannel and setting the OperationTimeout property) and ensure that the service is able to connect to the client.
however, if I try to use other actions, such as search information or add registers and any other kind of operation, the application works fine.
So the problem is in the transfer of the file.
In the service I use this configuration:
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="tcpBinding"
name="NetTcpBindingEndpoint"
contract="GTS.CMMS.Service.IService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint contract="IMetadataExchange" binding="mexTcpBinding" address="net.tcp://localhost:5000/mex" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="behaviorConfig">
<!--
<serviceMetadata httpGetEnabled="true" />-->
<!--Necesario para poder enviar excepciones desde el servicio al cliente.-->
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="100" />
<serviceMetadata/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpBinding" maxBufferSize="67108864"
maxReceivedMessageSize="67108864" maxBufferPoolSize="67108864"
transferMode="Buffered" closeTimeout="00:00:10"
openTimeout="00:00:10" receiveTimeout="00:20:00"
sendTimeout="00:01:00" maxConnections="100">
<security mode="None"/>
<readerQuotas maxArrayLength="67108864" maxBytesPerRead="67108864" maxStringContentLength="67108864"/>
<reliableSession enabled="true" inactivityTimeout="00:20:00" />
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
And in the client:
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IService" 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:20:00"
enabled="true" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<messa
ge clientCredentialType="Windows" />
Thanks.
Is your application is working well for small size file in kbs? if yes then for lager size file use transferMode="Streamed" instead of transferMode="Buffered". You have to change configuration accordingly.
If your application is not working for even smaller files there is a problem with your application.
Build your application and regenerate proxy and try to debug your application.
You can also refer these links
http://www.codeproject.com/Articles/166763/WCF-Streaming-Upload-Download-Files-Over-HTTP
http://www.codeproject.com/Articles/33825/WCF-TCP-based-File-Server

configuring WCF with <services> tag

I am trying to solve a WCF error found in my previous question. Basically, the error is:
The maximum string content length quota (8192) has been exceeded while reading XML data.
And someone suggested to use a services tag in my web.config to resolve my issue.
Now, I am facing a different problem. I can’t figure out how am I suppose to configure the services tag in my web.config to work correctly on my server. I always get the following error when I try to use the services tag:
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
Here is my web.config with the services tag added:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding
name="BasicHttpBinding_Service1"
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="10000"
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://localhost:53931/WCF/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_Service1"
contract="ServiceReference.Service1"
name="BasicHttpBinding_Service1" />
</client>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<!--PROBLEM SOMEWHERE IN THE SERVICES TAG-->
<services>
<service
behaviorConfiguration="NewBehavior"
name="AspPersonalWebsite.ServiceReference">
<endpoint
address="http://localhost:53931/WCF/Service1.svc"
binding="basicHttpBinding"
contract="ServiceReference.Service1"
bindingConfiguration="BasicHttpBinding_Service1" />
</service>
</services>
Please note that by removing the services tag everything works fine, but then I will not be able to resolve my original problem posted on my previous question.
so could someone please tell me if I am doing something wrong on my web.config, specifically in my services tag?!
Okay, let's tackle this:
First, you need to define a custom basicHttpBinding binding configuration with some custom settings:
<bindings>
<basicHttpBinding>
<binding name="LargeSettings"
maxBufferSize="524288"
maxBufferPoolSize="524288"
maxReceivedMessageSize="6553600">
<readerQuotas maxDepth="32" maxStringContentLength="100000"
maxArrayLength="16384" maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
This section needs to be in both your server-side's web.config, as well as your client side's config.
Secondly, on the server-side, you need to have a <services> tag that defines your service and its endpoints and their configuration:
<services>
<service name="YourNamespace.YourClassName"
behaviorConfiguration="ServiceWithMetadata">
<endpoint name="Default"
address="http://localhost:53931/WCF/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="LargeSettings"
contract="YourNamespace.IServiceContract" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceWithMetadata">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Points to check:
your service name must be the fully qualified name (YourNamespace.YourClassName) of your service class - the class that implements your service contract
your service contract in the endpoint must also be the fully qualified name of your service contract (YourNamespace.IYourServiceContract)
the behaviorConfiguration of your <service> tag must reference and match exactly to the name= attribute as defined in your <behaviors> section
And thirdly, on the client side, you need something like this:
<client>
<endpoint name="Default"
address="http://localhost:53931/WCF/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="LargeSettings"
contract="ServiceReference.IYourService" />
</client>
You need to reference the endpoint defined in your service's definition on the server side, you need to use the same binding and binding configuration, and you need to use the service contract as defined in your service reference.
For those using the built in service reference, just use the .Endpoint.Binding =THE NEW BINDING
ex:
BasicHttpBinding b = new BasicHttpBinding();
b.Security.Mode = BasicHttpSecurityMode.Transport;
...
b.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
MyWebServiceReference.ServiceReferenceSoapClient objRE = new MyWebServiceReference.ServiceReferenceSoapClient("ServiceReferenceSoap", "URI");
objRE.Endpoint.Binding = b;
Use this setting for the your bindings,
<basicHttpBinding>
<binding maxReceivedMessageSize="2147483647" messageEncoding="Text" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" >
<readerQuotas maxStringContentLength="525288"></readerQuotas>
</binding>
</basicHttpBinding>

hosting WCF service in IIS with windows authentication and without anonymous access

I would like to use WCF service hosted in IIS (5/6) with integrated windows authentication enabled and anonymous access disabled. I tried to do this by following http://msdn.microsoft.com/en-us/library/ff648431.aspx, but getting an error saying certificate is not installed. But I don't need SSL. I don't have any clients expecting older ASMX services, so I don't need to use basicHttpBinding (and also it is not secure), so I tried to use wsHttpBinding.
How do I get wsHttpBinding with windows authentication to work without SSL? This is such a common requirement, but I couldn't find any solution for this. Can someone post the configuration for the client and the server please? I am using ASP.NET client.
My configuration below. and the exact error message is:
An error occurred while making the HTTP request to
https://mymachine/WCFTest/Service1.svc. This could be due to the fact
that the server certificate is not configured properly with HTTP.SYS
in the HTTPS case. This could also be caused by a mismatch of the
security binding between the client and the server.
I used "svcUtil" utility to generate the proxy class and configuration for the client.
server:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="Transport"/>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="WCFTest.Service1Behavior" name="WCFTest.Service1">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" name="wsHttpEndpoint" contract="WCFTest.IService1"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFTest.Service1Behavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
client:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpoint" 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="Transport">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://mymachine/WCFTest/Service1.svc"
binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint"
contract="IService1" name="wsHttpEndpoint">
<identity>
<userPrincipalName value="mymachine\ASPNET" />
</identity>
</endpoint>
</client>
</system.serviceModel>
I ended up using basicHttpBinding as explained in the article http://msdn.microsoft.com/en-us/library/ff648505.aspx. posting the config for the client and the server below if anyone is interested. client config is generated using "svcutil".
server config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="WCFTest.Service1Behavior" name="WCFTest.Service1">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="BasicHttpEndpointBinding"
name="BasicHttpEndpoint" contract="WCFTest.IService1">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFTest.Service1Behavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
client config:
<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" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://machinename/WCFTest/Service1.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpoint"
contract="IService1" name="BasicHttpEndpoint" />
</client>
</system.serviceModel>

WCF Service Name & Binding Name

Scenario
I have two WCF Services combined in a single App.Config file.
I can't get the thing to run (the application compiles but fails at initialization of the services).
Question
I'm wondering whether I need to set the service name to be the same as something else that is also defined as part of the service overall?
ERROR
TypeInitializationException
{"Service 'MurexUploadObjects.ResponseService' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element."}
CODE
<system.serviceModel>
<configuration>
<behaviors>
<serviceBehaviors>
<behavior name="Service1Bevhavior">
</behavior>
<behavior name="Service2Bevhavior">
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpBloombergServiceEndPoint" 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:05:00"
enabled="true" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
<binding name="TransactedBinding">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<services>
<!--SERVICE ONE-->
<service name="INSERT NAME HERE">
<endpoint address="net.tcp://AP434190:8732/BloombergService/"
binding="netTcpBinding"
contract="BloomberPriceListenerService.IBloombergPriceListenerService"
bindingConfiguration="tcpBloombergServiceEndPoint"
name="tcpBloombergServiceEndPoint" />
</service>
<!--SERVICE TWO-->
<service name="INSERT NAME HERE">
<endpoint address="net.tcp://localhost:8735/private/MurexUploadObjects/ResponseService"
binding="netTcpBinding"
contract="MurexUploadObjects.IResponseService"
bindingConfiguration="TransactedBinding"
name="TransactedBinding"/>
</service>
</services>
</system.serviceModel>
</configuration>
The service name must be the fully qualified name of your service class, including the namespace, e.g.
<service name="YourServiceNamespace.YourService">
It can't be just anything - the name of the service class is used by ServiceHost to find the right service configuration.