I am trying to configure my wcf service to use a wsDualHttpBinding over https.
My current config looks like this:
Service
<service behaviorConfiguration="SecureBackendWebServiceBehavior"
name="WebService.InternalService.BackendWebService">
<endpoint address=""
binding="wsDualHttpBinding"
bindingConfiguration="SecureBackendWebServiceWsDualHttpBinding"
name="BackendWebServiceEndpoint"
contract="WebService.InternalService.IBackendWebService"/>
</service>
Binding
<binding name="SecureBackendWebServiceWsDualHttpBinding"
receiveTimeout="00:05:00"
bypassProxyOnLocal="false"
transactionFlow="true"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
messageEncoding="Mtom">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
Behavior
<behavior name="SecureBackendWebServiceBehavior">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
When i call the service in my browser it says:
No baseaddress for schema "http" found with the the endpoint binding WSDualHttpBinding. Registered baseaddressschema is [https].
By googeling the problem I only end up with samples for normal wsHttpBindings but nothing for the dual binding. I already enterd a HttpsGetUrl but ended up with the same error.
Have I overseen some value, or why is he trying to get the information over http?
Btw. changing the binding to NetTcp is not an option!
Hope any of you can help me here.
thx
wsDualHttpBinding doesn't support transport security.
MSDN:
The WSDualHttpBinding provides the same support for Web Service protocols as the WSHttpBinding, but for use with duplex contracts. WSDualHttpBinding only supports SOAP security and requires reliable messaging.
So you can rely on message security here only.
Found a solution on my own. I used the patterns & practices Improving Web Services Security: Scenarios and Implementation Guidance for WCF to get a better understanding of security in WCF. This book also includes HowTos for certain scenarios. Only thing I had to do additional.
Because my Web Service is separated in three smaller services, one of them is using the WsDualHttpBinding I needed to tell iis that this one doesn't requires the ssl certificate for transport.
For now on my service talks, but I need to check if it really uses the security I want to have.
UPDATE:
Found this article that also contains a step by step tutorial.
Related
I have a WCF service hosted on IIS that is working perfectly well over https with SSL. It has the following simple binding setup...
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding maxBufferSize="524288"
maxBufferPoolSize="1048576"
maxReceivedMessageSize="524288">
<readerQuotas maxStringContentLength="262144" maxArrayLength="65536" />
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
Is it possible to have another basicHttpBinding but without the security mode so that clients can connect with http or https. Do I just copy and paste the binding and remove the security mode on the copy? Or will that cause confusion because there are two bindings of the same type but they do not have names?
You have to create another binding and add an additional endpoint to use the binding without security. A binding is only a description HOW an endpoint should be created, but the binding configuration does not open any endpoints. You can have many endpoints using the same binding, but only one binding per endpoint.
My call to my WCF web service is failing with System.Net.WebException: The request failed with HTTP status 413: Request Entity Too Large.
Checking Fiddler, I see that I'm sending:
Content-Length: 149839
Which is over 65KB.
Enabling WCF tracing on the server, I see:
System.ServiceModel.ProtocolException: 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.
Adding this property doesn't solve the issue.
I've tried with just that property, and (later) with various others that posts have suggested. Here's what I have currently (on the server):
<basicHttpBinding>
<binding name="PricerServiceSoap"
closeTimeout="00:10:00" openTimeout="00:10:00"
receiveTimeout="00:10:00" sendTimeout="00:10:00"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
My sole endpoint (under <client>) is:
<endpoint address="/NetPricingService/Service.asmx"
binding="basicHttpBinding" bindingConfiguration="PricerServiceSoap"
contract="Pricing.PricerService.PricerServiceSoap"
name="PricerServiceSoap" />
I've also added:
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
under <behavior>.
I've even run (for IIS 7):
%windir%\system32\inetsrv\appcmd set config "WebServicesDev/PricingService"
-section:requestFiltering -requestLimits.maxAllowedContentLength:104857600
-commitpath:apphost
Nothing makes any difference.
One catch is that this is a WCF service meant to replace an older ASMX service. The service skeleton was generated with svcutil from existing WSDL. I can't change the client configurations (and the clients are in multiple languages). My test client project imported the service with Add Web Reference (under Add Service Reference / Advanced), so I have no WCF configuration. However, the test client works if I point it at the older ASMX service.
How can I fix or diagnose this?
Additional info
If I use the Microsoft Service Configuration Editor to generate the config (setting maxReceivedMessageSize and maxBufferSize), it works. The problem is that the endpoint is then specified under <service>, and it won't let me specify the /NetPricingService/Service.asmx relative address. If I edit the bindings in the svcutil-generated config (where the endpoint is under <client>), it doesn't work with large requests.
The answer was staring me in the face.
The config generated by svcutil was for the client. I was using it on the server.
I was editing the bindings for the endpoints specified under <client>, which made absolutely no difference to the service.
Adding a proper <service> endpoint and setting the maxReceivedMessageSize and maxBufferSize on its binding resolved the issue.
I had a similar problem.
For me, the problem was that my endpoint did not explicitly name the binding using bindingConfiguration and so must have been using some default one somewhere.
I had:
<webHttpBinding>
<binding
name="myXmlHttpBinding"
maxReceivedMessageSize="10485760"
maxBufferSize="10485760">
<readerQuotas
maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="None"/>
</binding>
</webHttpBinding>
and my endpoint defined as:
<service
name="blah.SomeService">
<endpoint
address=""
behaviorConfiguration="WebHttpBehavior"
binding="webHttpBinding"
contract="blah.ISomeService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
It worked once I changed the endpoint to:
<service name="blah.SomeService">
<endpoint address=""
behaviorConfiguration="WebHttpBehavior"
binding="webHttpBinding"
bindingConfiguration="myXmlHttpBinding"
contract="blah.ISomeService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
I also had this problem and realized in fiddler that the max Content-Length that was working ended up being 30000000.
After verifying that my WCF configuration was correct I found an article suggesting a modification to the IIS setting, Request Filtering.
Large file upload failure for Web application calling WCF service – 413 Request entity too large
Open IIS Manager
Select your application
Select the Request Filtering icon.
Select Edit Feature Settings... (Right Panel)
Adjust the Maximum allowed content length (Bytes) Default Appears to be 30000000
or web.config file example
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="50000000" />
</requestFiltering>
</security>
</system.webServer>
tried things from 10 different blogs and my coworker figured it out.
we had to add a basicHttpsBinding section inside of in addition to the basicHttpBinding section. We have a webapi service calling wcf. the webapi method was catching the entity too large error when it called the wcf service method. This change was applied in the web.config file of the wcf service.
None of the suggestions worked for me. What solved the issue was to increase the MaxReceivedMessageSize in System.ServiceModel.Channels.HttpTransportBindingElement
There are two different MaxReceivedMessageSize parameters:
MaxReceivedMessageSize in
System.ServiceModel.Configuration.BasicHttpBindingElement
MaxReceivedMessageSize in
System.ServiceModel.Channels.HttpTransportBindingElement
In the dump file, I saw that it was failing because of the limitation in HttpTransportBindingElement
Adding this to my web.config fixed the issue:
<customBinding>
<binding closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00">
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" useDefaultWebProxy="true" transferMode="Buffered" />
</binding>
</customBinding>
Source: WCF service shows 413 Request Entity Too Large error when uploading files over 64 KB
Add this solve it for me:
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_Example"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
</binding>
</basicHttpBinding>
</bindings>
I followed this tutorial (at least based my WCF in this, coz I need then to work alike):
http://www.eggheadcafe.com/tutorials/wcf/b5ada8df-58c5-492f-b368-457b3a4f137c/notify-client-applications-using-wcf-callbacks.aspx
It's working very well on my computer, but i need to use it over the internet. While trying to do this I heard (over the internet) that is better to use netTcpBiding.
I gonna have a server that is going to be aware of the number of clients online. I wanted a WFC service on my IIS in the server, and a windows service consuming it and notifying it. I need the callback coz the server sometime have to be able to execute some commands on the client.
I would be very pleased if anyone could help me.
Thanks in advance,
Edit:
Making myself clear: I just could not make it work over the internet. Can you guys show me how can i change my configurations (Web.config e App.config) to use netTcpBinding and work over the internet?
Thanks again,
Edit 2:
My Web.config in my WCFServiceApplication is:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IPCWatcherWCFService" 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>
<services>
<service behaviorConfiguration="TiT.PCWatcher.Server.WCFService.Services.PCWatcherWCFServiceBehavior" name="TiT.PCWatcher.Server.WCFService.Services.PCWatcherWCFService">
<endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IPCWatcherWCFService" contract="TiT.PCWatcher.Server.WCFService.Interfaces.IPCWatcherWCFService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="TiT.PCWatcher.Server.WCFService.Services.PCWatcherWCFServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
My App.config in my WindowsService is:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IPCWatcherWCFService" 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>
<client>
<endpoint address="http://localhost:25145/Services/PCWatcherWCFService.svc"
binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IPCWatcherWCFService"
contract="PCWatcherWCFServiceReference.IPCWatcherWCFService"
name="WSDualHttpBinding_IPCWatcherWCFService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
Just changing it to netTcpBinding does not work...
But i would be glad enough to jut be able to run this over the internet... I published the WCFService on IIS. Links:
https://www2.tcenter.com.br/monitor/PCWatcherWCFService.svc
OR
http://www2.tcenter.com.br:8080/monitor/PCWatcherWCFService.svc
Just changing the configs its enought to make it work through the internet? like i said, local it works just fine.
I thought that just changing the endpoint address on the client to one of the URL's above it whould work, but it did not...
The example that you linked hosts the service on the WPF. I don't know if it applys to my cenario...
i Think i'm gonna stick with the DualHttpBinding, you don't think that port forwarding it's good for my needs, i'm can have a lot of clients in one intranet and having the router decide wich one he is going to send info for it's no good right? or there's a way to make the router respond corretly to each and every machine conecting to my webserver through the same port?! (just asking, hehehe)
Thanks a lot in advance,
Edit on 21/06/2012:
Thanks for the reading.
I was not able to get the service to work with netTcpBinding in LAN.
I did a mock sample of my cenario. It's here. Called DualCommunicationTest.
When I started this post, i just wanted to know how to make this cenarion runing on internet. Just that.
During my time searching for a solution before posting here, i readed that netTcpBinding is better. So i asked about it. It was just a side question.
So... my current needs on the post are:
How to use the sample i developed on the internet.
OR
How to make the sample i developed work with netTcpBinding AND then be able to use it on the internet. (I'm pretty sure Clunky Coder taught me the second part, on how to publish a net.tcp on the internet with the IIS and stuff, thanks a lot for that, but i was not able to test it yet, because i couldn't do a netTcp yet.)
I'm sorry if i'm not been clear enough, my English is not so good. sry and thanks again, a lot.
netTcpBinding is better for duplex communication (communication with callbacks) and it's more performant than WSDualHttpBinding which is the preferred binding for duplex communication over HTTP. But you shouldn't really use netTcpBinding over the internet although you technically can and it might work, but the ports that netTcpBinding uses may be (and usually are) blocked by firewalls on the internet. When you send something across the internet, it makes lots of hops and goes through lots of routers and firewalls, and there is no guarantee that those routers and firewalls will have all ports open. But if you can open the ports (for netTcp it's TCP 808) on both the client and server endpoints (usually done by port forwarding on the router) it may work, but the general advice is not to use netTcpBinding over the internet. Having said that I have used it a couple of times for my services, and my clients have been able to consume the service over the internet without any problems-after I forwarded the ports on both the client and server ends.
In general for duplex communication over the internet you have the WSDualHttpBinding and if you have a Silverlight client (Silverlight doesn't support WSDualHttpBinding) you can use PollingDuplexHttpBinding.
I also recommend you read this.
EDIT:
To change that example to use netTcpBinding, just change the bindings in the config file to use netTcpBinding instead of wsDualHttpBinding. Have a look at this article, it does what the link you posted does, with netTcpBinding and more explanation.
EDIT 20/06/2012:
Making myself clear: I just could not make it work over the internet.
Can you guys show me how can i change my configurations (Web.config e
App.config) to use netTcpBinding and work over the internet?
Seems that you were able to get the service to work with netTcpBinding in LAN, so your earlier problem is now fixed and you're now having trouble hosting the service in IIS and publishing it online. When your service works in a LAN, it will work over the internet once you host it in IIS and forward the appropriate ports on the clients and servers routers, this is a common scenario and is documented well online. To do this You must host your service as an application in your IIS website. You need to make sure your service has a .svc file that points to the location of the service, then copy the contents of
the App.Config (Service config file) to a new web.config (in the same physical directory as your App.config) and also remove the <host><baseAddresses> section in the newly created web.config, point the physical path of the application to the location of this service on your service host computer. Once that's taken care of, just be sure to edit the default website bindings to enable the specific bindings your service uses, for netTcpBinding go to: Website -> 'Edit Bindings...' -> 'Add...' then choose net.tcp and assign it the ports.
Then on your application go to 'Advanced Settings' and enable net.tcp, netTcpBinding service will typically have http,net.tcp as it's enabled protocols. If you run into teething errors make sure the default app pool (or which ever application pool your website is using) has the required permissions to access and read the physical directory on the server in which the service resides.
Please read this and this, asking me to elaborate would just be repeating what they're saying.
EDIT 21/06/2012:
I just downloaded your service and hosted it in IIS and it's hosted fine, since its using HTTP and not nettcp then that means it works perfectly fine on the internet. If your service is something simple and you don't expect to do heavy processing with it (by the looks of it you're just trying to get the list of clients connected to it) then stick with wsDualHTTPBinding since the HTTP protocol will work in any environment and you don't have to worry about firewalls as you would with netTcpBinding. This is all I did to host the service in IIS (and make it available over the internet):
Go to DefaultWebsite in IIS, right click, add application, under Alias just give your service any name you wish to be able to see in the URL. Select Default App Pool or ASP.NET 4.0 app pool.
Point the physical path to where your .svc file is on your computer; for me its:
C:\Users\MyPC\Documents\DualCommunicationTest.Server\WcfServiceApp
Under enabled protocols ensure that you have HTTP on port 80 or any other port, for example 8085, but you will need to forward this port on your router to the Service host computer. If your Service host is on IP 192.168.1.4 in your LAN, then on your router forward port 80 (or whatever port you use-say 8085) to computer 192.168.1.4.
And it's that easy.
TCP binding is better for callbacks over the internet because TCP is dual direction by nature.
HTTP is a request, it is one way only. Hence the dual in dualHttpBinding. WCF has to create a second HTTP connection back to the client so the service can send requests to the client.
The Internet is not really set up for servers to call back via HTTP. Things like NAT being performed by routers means that ports must be forwarded in order to route the HTTP request properly, and the client would have to be running an HTTP server.
So, it is much easier to use TCP. Either that or possibly have the client request a reply object that is streamed from the server end (a never ending reply in effect), that the server can fire notifications down. This isn't simple though.
I have deployment of WCF service on IIS 7 with support for Non-HTTP enabled
Under one project, I have exposed 8 different services with wsHttp endpoints which works fine.
I want to also expose NetNamedPipe bindings for the same services.
My sample NetNamedPipe bindings . . .
<netNamedPipeBinding>
<binding name="PassportIPCBasicEndpoint"
closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:10:00"
sendTimeout="00:05:00"
maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647" transferMode="Buffered"
hostNameComparisonMode="Exact" >
<readerQuotas
maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="Transport">
<transport protectionLevel="None" />
</security>
</binding>
</netNamedPipeBinding>
And my Service tags
<service behaviorConfiguration="default" name="MyAccountService.AccountService">
<host>
<baseAddresses>
<add baseAddress="http://localhost/MyAccountService/v1.0/AccountService.svc" />
</baseAddresses>
</host>
<endpoint name="PassportIPCBasicEndpoint"
address="net.pipe://localhost/MyAccountService/v1.0/AccountService.svc"
binding="netNamedPipeBinding"
bindingConfiguration="PassportIPCBasicEndpoint"
contract="MyAccountService.IAccountService"/>
</service>
This gives me following exception :
The protocol 'net.pipe' is not supported.
[InvalidOperationException: The protocol 'net.pipe' is not supported.]
System.ServiceModel.Activation.HostedTransportConfigurationManager.InternalGetConfiguration(String
scheme)
[InvalidOperationException: The ChannelDispatcher at
'net.pipe://localhost/MyAccountService/v1.0/AccountService.svc' with
contract(s) '"IAccountService"' is unable to open its
IChannelListener.]
I have added entry for http,net.pipe in advanced site settings in IIS.
Non-HTTP support for WCF service is also installed and enabled through control panel settings.
out of 8 .svc services only one such service is able to get hold of port and I can browse it's .SVC endpoint
all other services when configured for netnamedPipe binding give me above errors.
Can some body guide me, what needs to be done to make them all get hold on port and be accessible.
This problem was with enabling the protocols at the correct place.
Previously i had enabled net.pipe protocol at site level.
After enabling net.pipe protocol at each virtual path of the hosted services.
It worked.
The netNamedPipe binding is only for on-the-same-machine communication - you cannot call such an endpoint from a remote machine.
Is that what you're trying to do??
netNamedPipe binding is great for intra-application communication on the same machine - but not for anything else, really.
I am creating a web service that will be consumed by a single client in another part of the world. I don't have any knowledge or control over the technology they are using but have been asked to
"use SSL to encrypt the message during transport and use UsernameToken
for client authentication"
I'm planning to use WCF4 to create the service and know generally how to set this all up. However I'm struggling to find the correct configuration for bindings etc. Google gives me lots of results around WSE 3.0 but I'm pretty sure (please correct me if I'm wrong) that I shouldn't be using WSE for a WCF service.
This article initially seems to suggest I should be using a custom binding but then also says I should "consider using the WCF system-defined bindings with appropriate security settings instead of creating a custom binding". However I can't see any examples of what this should be.
I would be grateful if anyone can point me in the right direction.
tl;dr: What are the WCF4 config settings to support SSL and UsernameToken?
Take a look at the WsHttpBinding. You can use a security mode of TransportWithMessageCredential to use SSL and a message credential of UserName. If you are hosting in IIS set up SSL there.
You can set up the binding in config as follows.
<bindings>
<wsHttpBinding>
<binding name="secureBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
You can then use this binding config as follows
<services>
<service name="ServiceName">
<endpoint address="" binding="wsHttpBinding" contract="ContractType" bindingConfiguration="secureBinding" />
</service>
</services>
Both these elements are children of the system.serviceModel element in config.