HTTP and HTTPS Bindings - c#

I have a application that consumes a WCF web service.
I have it cofigured to use a https binding. It works fine. I also wanted to add a HTTP binding to the same.
My requirement is if my client is on my domain (or on VPN) i need them to use the HTTP binding. and if they are external clients I want them to use HTTPS binding. How can I go about doing that? I am very new to WCF and this is my first try on it.
I have attached my Config File for reference. I did not know where to add the end point for the HTTP binding. Any help would be appriciated.
<system.serviceModel>
<services>
<service name="{service name}"
behaviorConfiguration="httpsBehavior">
<!--HTTPS END POINT-->
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="SecureHTTPBinding"
contract="{service contract}" />
<!--METADATA ENDPOINT-->
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="httpsBehavior">
<serviceMetadata httpsGetEnabled="true" httpsGetUrl="" />
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
<behavior name="httpBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<!--HTTPS BINDING-->
<binding name="SecureHTTPBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
<!--HTTP BINDING-->
<binding name="BasicHttpBinding">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
EDIT : Adding netTCP Binding
<system.serviceModel>
<services>
<service name="{Service Name}"
behaviorConfiguration="httpsBehavior">
<!--HTTPS END POINT-->
<endpoint address="https://localhost/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="SecureHTTPBinding"
contract="{Service Contract}" name="httpsEndPoint"/>
<!--METADATA ENDPOINT-->
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
<!--HTTP END POINT-->
<endpoint address="http://localhost/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="HttpBinding"
contract="{Service Contract}" name="httpsEndPoint"/>
<!--TCP METATADATA END POINT-->
<endpoint address="mextcp" binding="mexTcpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:808/Service1.svc" />
</baseAddresses>
</host>
<!--TCP ENDPOIN-->
<endpoint address="net.tcp://localhost:808/Service1.svc" binding="netTcpBinding" contract="{Service Contract}" name="netTCPEndPoint" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="httpsBehavior">
<serviceMetadata httpsGetEnabled="true" httpsGetUrl="" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<!--HTTPS BINDING-->
<binding name="SecureHTTPBinding" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32"
maxArrayLength="200000000"
maxStringContentLength="200000000"/>
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
<!--HTTP BINDING-->
<binding name="HttpBinding" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32"
maxArrayLength="200000000"
maxStringContentLength="200000000"/>
<security mode="None" />
</binding>
</basicHttpBinding>
<!--TCP BINDING-->
<netTcpBinding>
<binding transferMode="Buffered" />
</netTcpBinding>
</bindings>
I am aware of the the possible Dos attacks wrt to the numbers in the code and I would work around it. For now just wanted to get it working. When I use this config file I run into error that says
Could not find a base address that matches the scheme net.tcp for the endpoint MetadataExchageTcpBinding. Registered base addresses are [http,https]
Can some one help me expose a net.tcp binding for my service.
Any help would be appriciated

Use netTcpBinding for your domain clients. Your network firewall will almost certainly block raw TCP traffic by default while letting in HTTP traffic, so it will naturally ensure that each client goes to the appropriate endpoint. You may very well get an extra performance boost for domain clients into the bargain.
If you don't want to do that (e.g. your WCF host doesn't support it, or you have problems with VPN clients), then just expose one HTTPS endpoint for all clients regardless of location. The cost of SSL will be trivial compared to the overhead of doing a cross-network call in the first place.
Background:
netTcpBinding transmits data in a compact binary format, which is more efficient than sending XML text over HTTP. The downsides are: it is not compatible with non-.NET clients, and you have to open specific ports on the firewall to let it through. Neither of those issues will be a problem for your scenario though.
You can expose any number of endpoints in a WCF service, as long as they all have unique distinct combinations of Address/Binding/Contract. You can therefore expose both HTTPS and TCP endpoints to the same service because they will have different Addresses and Bindings.

Related

WCF - HTTPS - Transport security works but message security throws exception on application startup

I have a WCF self hosted server (a console application which registers the wcf contract with castle ioc container AsWcfService). I need it to work securely over https.
When I configure the server to use wsHttpBinding with security mode=Transport and clientCredentialsType=None, everthing works fine.
The configurations looks as follows:
Transport Security Configuration
<behaviors>
<serviceBehaviors>
<behavior name="secureBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" httpsHelpPageEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="secureBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" sendTimeout="01:00:00">
<security mode="Transport" >
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="service" behaviorConfiguration="secureBehavior">
<endpoint binding="wsHttpBinding" bindingConfiguration="secureBinding" contract="Contract.Service" />
<host>
<baseAddresses>
<add baseAddress="https://domain-name:port-number/"/>
</baseAddresses>
</host>
</service>
</services>
The above works fine.
Message Security Configuration
<behaviors>
<serviceBehaviors>
<behavior name="secureBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" httpsHelpPageEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="secureBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" sendTimeout="01:00:00">
<security mode="Message" >
<message clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="service" behaviorConfiguration="secureBehavior">
<endpoint binding="wsHttpBinding" bindingConfiguration="secureBinding" contract="Contract.Service" />
<host>
<baseAddresses>
<add baseAddress="https://domain-name:port-number/"/>
</baseAddresses>
</host>
</service>
</services>
With message security configuration, however, when I try to start the server I get the following exception:
Could not find a base address that matches scheme http for the
endpoint with binding WSHttpBinding. Registered base address schemes
are [https]. System.InvalidOperationException: Could not find a base
address that matches scheme http for the endpoint with binding
WSHttpBinding. Registered base address schemes are [https].
I can't find the reason for this error anywhere I look.
An explanation would be highly appreciated.

WCF Debugging a REST api

The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.
My section in the configuration file
<system.serviceModel>
<services>
<service name="RestAPI.RiskEventAPI" behaviorConfiguration="metadataBehavior">
<endpoint address=""
binding="basicHttpBinding"
contract="RestAPI.IRiskEventAPI"/>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
<behavior name="RestAPI.RiskEventAPIBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="REST">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="BindingWithMaxSizeIncreased"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
it's confusing with the web going all over the place and nothing specific to REST and WCF. the debug window comes up but I get the error at the top of this question...
this didn't affect anything:
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="BindingWithMaxSizeIncreased"
contract="RestAPI.IRiskEventAPI"/>
copying
<webHttpBinding> to <basicHttpBinding> didn't help either
I tried this...i used the wcf editor and added a mexHttpBinding but it has issues with maxBufferSize, maxBufferPoolSize and maxReceivedMessageSize (says they're not allowed)
<mexHttpBinding>
<binding name="bindingMex"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"/>
</mexHttpBinding>
i tried this (didn't work either):
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="IncreasedBindingMaxSize" contract="IMetadataExchange" />
...
<basicHttpBinding>
<binding name="IncreasedBindingMaxSize" maxBufferSize="2147483647"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
I think the reason you're running into this issue is because you don't appear to have an explicitly defined endpoint for the webHttp, and you're not using default bindings in the configuration (i.e., a <binding> element with no name attribute).
This means that the system will use the default (smaller) values for the webHttpBinding. It's not clear if you're wanting to do both SOAP and REST endpoints for your service - you have an explicitly defined endpoint using basicHttpBinding that appears to be geared towards SOAP, but I'm not sure.
What you can do is change your service endpoint and use webHttpBinding, the REST behavior and explicitly assign your larger binding configuration "BindingWithMaxSizeIncreased" to that endpoint via the bindingConfiguration attribute on the <endpoint> element in the ` section, like this:
<endpoint address=""
behaviorConfiguration="REST"
binding="webHttpBinding"
bindingConfiguration="BindingWithMaxSizeIncreased"
contract="RestAPI.IRiskEventAPI"/>
If you do need the basicHttpBinding endpoint, you can add another endpoint with the webHttpBinding, though you may need an address different than address="", maybe something like address="REST".

Support both HTTP and HTTPS Web.Config WCF Service

I'm running into a configuration problem with my WCF service when trying to support both https and https. Ideally what I'd like is to run http on my dev machine and then publish to azure running https.
I followed these posts to try and run the configuration:
http://jayakrishnagudla.blogspot.com/2009/12/configuring-wcf-services-to-work-with.html
How to configure a single WCF Service to have multiple HTTP and HTTPS endpoints?
My Web.Config is as follows:
<system.serviceModel>
<services>
<service name="Backend.Services.UserService.UserService" behaviorConfiguration="">
<endpoint address=""
binding="webHttpBinding"
contract="Backend.Services.UserService.IUserService"
bindingConfiguration="HttpsBinding"
behaviorConfiguration="Web">
</endpoint>
<endpoint address=""
binding="webHttpBinding"
contract="Backend.Services.UserService.IUserService"
bindingConfiguration="HttpBinding"
behaviorConfiguration="Web"
>
</endpoint>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name ="HttpBinding">
<security mode="None">
<transport clientCredentialType="None"/>
</security>
</binding>
<binding name="HttpsBinding">
<security mode="Transport"/>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="Web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
As far as I can tell, this configuration should be correct according to the above links. However, when I build and run this service locally via http I get the following error:
Could not find a base address that matches scheme https for the endpoint with binding WebHttpBinding. Registered base address schemes are [http].
I'm not quite sure where the problem is and assume its a misconfiguration. Any help would be appreciated.
I've been trying to do this for days (years actually, but just restarted a few days ago), and the post above pointed me in the right direction with protocolMapping, but you need to specify the bindingConfiguration in the protocolMapping section to make it choose the <security mode=None> or <security mode=Transport>:
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<protocolMapping>
<add scheme="http" binding="basicHttpBinding" bindingConfiguration="ServiceBinding"/>
<add scheme="https" binding="basicHttpBinding" bindingConfiguration="ServiceBindingSSL"/>
</protocolMapping>
Leave the bindingConfiguration attribute off of the endpoint - it will be set automatically based on the protocol. Then set up the second binding configuration in your bindings section:
<basicHttpBinding>
<binding name="ServiceBinding" ...>
<security mode="None">
</security>
</binding>
<binding name="ServiceBindingSSL" ... >
<security mode="Transport">
</security>
</binding>
</basicHttpBinding>
This technique worked for me. Hope it helps you!
i finally got it working for HTTP & HTTPS, based on Rick Moss' answer. except that i did not leave away the bindingConfiguration off the endpoint, because it caused a no endpoint listening error:
<configuration>
...
<system.serviceModel>
<services>
<service name="WcfService1.Service1">
<endpoint address="" name="ep1" binding="webHttpBinding" bindingConfiguration="ServiceBinding" contract="WcfService1.IService1" behaviorConfiguration="WebBehavior" />
<endpoint address="" name="ep1" binding="webHttpBinding" bindingConfiguration="ServiceBindingSSL" contract="WcfService1.IService1" behaviorConfiguration="WebBehavior" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="ServiceBinding" ...>
<security mode="None">
</security>
</binding>
<binding name="ServiceBindingSSL" ...>
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
...
</behaviors>
<protocolMapping>
<add scheme="http" binding="basicHttpBinding" bindingConfiguration="ServiceBinding"/>
<add scheme="https" binding="basicHttpBinding" bindingConfiguration="ServiceBindingSSL"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
...
</configuration>
EDIT: this only seems to work with Anonymous authentication in IIS. Enabling Windows Authentication in a different web service under the same website in IIS caused:
Could not find a base address that matches scheme https for the endpoint with binding WebHttpBinding. Registered base address schemes are [http].
i hate Web.config files. they're too tightly coupled to IIS
Have you looked at the protocol mapping wcf configuration section?
<protocolMapping>
<add scheme="http" binding="wsHttpBinding"/>
<add scheme="https" binding="wsHttpBinding"/>
</protocolMapping>
Edit : I am not sure why you have configured an "https" binding under the webHttpBinding type. Shouldn't you have both http webHttpBinding and wsHttpBinding defined and assigned to your endpoint?
<webHttpBinding>
<binding name ="HttpBinding">
<security mode="None">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>

wsDualHttpBinding Not Working When Deployed Under Azure

WCF Duplex not working under Azure.
Everything works fine under IIS Express.
I know duplex binding is problematic because of the server callback, but....
I already shut down my firewall.
TCPView (Sysinternals) shows 10 to 12 packets being sent/received by the client and then it just dies... nothing happens.
I set to 10 minutes all timeouts i could.
Please see my config files below.
SERVER CONFIG:
<system.serviceModel>
<services>
<service behaviorConfiguration="MexBehaviour" name="MySrvc">
<endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="wsDualHttpBinding"
name="wsDualEndpoint" bindingName="wsDualHttpBinding" contract="IMySrvc" />
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="mexHttpBinding"
name="MexEndpoint" bindingName="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://srvc.azurewebsites.net/MySrvc.svc" />
</baseAddresses>
<timeouts openTimeout="00:10:00" />
</host>
</service>
</services>
<bindings>
<wsDualHttpBinding>
<binding name="wsDualHttpBinding" openTimeout="00:10:00" sendTimeout="00:10:00"
clientBaseAddress="http://xxx.xxx.xxx.xxx:xxx">
<security mode="None">
<message clientCredentialType="None" negotiateServiceCredential="false" />
</security>
</binding>
</wsDualHttpBinding>
<mexHttpBinding>
<binding name="mexHttpBinding" />
</mexHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MexBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
CLIENT CONFIG:
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="wsDualEndpoint">
<security mode="None" />
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="http://srvc.azurewebsites.net/MySrvc.svc"
binding="wsDualHttpBinding" bindingConfiguration="wsDualEndpoint"
contract="SrvcRef.IMySrvc" name="wsDualEndpoint" />
</client>
</system.serviceModel>
I knew this wsDualHttpBinding didn't pass the "smell test"....
From Juval Lowy's book, "Programming WCF Services: Mastering WCF and the Azure AppFabric Service Bus":
...the WSDualHttpBinding is mostly unusable, since it is practically impossible to tunnel through various communication barriers separating the service from the client and the need to find a specific web-server machine makes this impractical.
I solved my problem by simply using netTcpBinding instead....
You just need to get IIS to work with TCP protocol.
There's plenty of articles out there explaining how to do it.
Here's one:
http://msdn.microsoft.com/en-us/library/ms731053.aspx
Cheers.

WCF: The remote server returned an error: (413) Request Entity Too Large [duplicate]

This question already has answers here:
(413) Request Entity Too Large | uploadReadAheadSize
(15 answers)
Closed 8 years ago.
I have a wcf service
there is a method which gets base64 string to upload a file my file's size 100kb it may be larger in time
i got the error message: The remote server returned an error: (413) Request Entity Too Large
while try to get HttpWebResponse
this is my wcf service web.config
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpTransportSecurity" allowCookies="false" maxReceivedMessageSize="104857600">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" />
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="FHServices.FHSmartService" behaviorConfiguration="ServiceBehaviour">
<endpoint address="" binding="webHttpBinding" contract="FieldHoundServices.IFHSmartService" behaviorConfiguration="web">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost/FHServices/FHSmartService.svc/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
what is my mistake?
solved
i found my mistake
i remove these codes
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
i think transport mode for https and we have no ssl so we dont need transport mode. anyway after i remove it, everything seems ok now
You don't assign a defined WebHttpBinding configuration to your endpoint, so the endpoint uses the default values for the binding.
You can tell the endpoint to use your binding congfiguration by specifying it in the bindingConfiguration attribute on the <endpoint> element, like this:
<endpoint address="" binding="webHttpBinding"
bindingConfiguration="webHttpTransportSecurity"
contract="FieldHoundServices.IFHSmartService"
behaviorConfiguration="web">
</endpoint>

Categories