Background info:
I have some WCF services that are hosted on an internal server on a specific port. A hole was "punched" in the firewall to make the services on this port accessible from the DMZ. The consuming web app is hosted in the DMZ.
The internal server DOES NOT have an SSL cert.
The DMZ server DOES have an SSL cert.
The problem:
From all that I have read about WCF, my understanding is that I need an SSL cert on the server that hosts the WCF services. Is this correct?
At this time I have been told that we don't know when the internal server will have an SSL cert installed and that I need to come up with a Plan B.
I started looking into going back to ASMX/WSE and it looks like that is going to be a problem since WSE is no longer supported, it does not integrate with VS2008 and it is not compatible with x64 machines.
[rock]Me[hardplace]
The data will contain PII, so I'm quite considered about security...even if others are less concerned.
Are there any options I've overlooked? Have I misunderstood WCF security?
Advice?
This post seems somewhat similar.
UPDATE
Thanks to mikey's answer and comments I made some changes to my configuration. It took some trial and error and additional Googling...but it seems to be working now (I haven't performed any extensive testing yet). However, I don't know if this is sufficiently secure...
Adding my solution to the original post so I can mark mikey's answer as the answer.
My changes
Services:
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<dataContractSerializer maxItemsInObjectGraph="6553600" />
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpsGetEnabled="false" />
<!-- 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>
<bindings>
<wsHttpBinding>
<binding name="customBinding">
<reliableSession enabled="true" />
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="serviceBehavior" name="MyApp.WcfServices.MyService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="customBinding" contract="MyApp.WcfServices.IMyService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
Web App:
<bindings>
<wsHttpBinding>
<binding name="customBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="1048576" maxReceivedMessageSize="1048576"
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" enabled="true" />
<security mode="None">
<transport clientCredentialType="None" />
<message clientCredentialType="None" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://[Ip Address]:8943/MyAppWcfServices/Hosts/MyService.svc"
binding="wsHttpBinding" bindingConfiguration="customBinding"
contract="MyService.IMyService" name="customBinding" behaviorConfiguration="clientBehavior">
</endpoint>
</client>
Here are some options:
You don't need SSL for WCF. You can set security to "None" http://msdn.microsoft.com/en-us/library/ms731172.aspx or http://social.msdn.microsoft.com/forums/en-US/wcf/thread/271b1816-173c-4c76-a4c4-fd9fda4b5e91/ -- then you won't need an SSL cert. Since the traffic is only going between your web server and your app/wcf server the only folks who will be able to sniff it should be internal folks... At some point you have to trust your network is working as intended. I often use only HTTP (not SSL) for web services between app and web servers on the same network especially when speed is an issue.
use a self-signed certificate on the app server. Ensure that the web server in the DMZ is configured to trust the certificate (and/or its CA) and you should be good to go.
Related
Was wondeirng if anybody could get me out of my cross domain policy hell.
I have a duplex WCF service which uses netTcpBining, and the client is a Silverlight 4 app. When I self host the service, then it works perfectly and my Silverlight clients can consume the service with no problems. However when I host it in IIS 7, that's when the trouble starts. When I host it in IIS I'm able to see the service at:
http://localhost/Conference/VideoConferenceService.svc
And when I add a reference to the service which is hosted in IIS, and try to call it, I get a:
CommunicationException: Could not connect to
net.tcp://localhost/Conference/VideoConferenceService.svc. The
connection attempt lasted for a time span of 00:00:03.3071892. TCP
error code 10013: An attempt was made to access a socket in a way
forbidden by its access permissions.. This could be due to attempting
to access a service in a cross-domain way while the service is not
configured for cross-domain access. You may need to contact the owner
of the service to expose a sockets cross-domain policy over HTTP and
host the service in the allowed sockets port range 4502-4534.
Or if seeing the actual error helps inspire those who have seen it before, here is what it throws at me in Reference.cs:
I have checked out almost every solution suggested regarding solving the cross-domain policy error, and I've put my clientaccesspolicy.xml in my default website root in IIS, and also in wwwroot. I've also turned off all my firewalls. I'm able to see the policy at http://localhost/clientaccesspolicy.xml
and also at http://127.0.0.1/clientaccesspolicy.xml but I still get this error.
Here is my web.config for the service hosted in IIS 7:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<gcServer enabled="true" />
</runtime>
<system.web>
<compilation debug="false" />
</system.web>
<system.serviceModel>
<services>
<service name="VideoServer.VideoConferenceService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService" contract="VideoServer.IVideoConferenceService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:4502/VideoServer/" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IVideoConferenceService" portSharingEnabled="true" transactionFlow="false" transferMode="Buffered" listenBacklog="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="24.20:31:23.6470000" openTimeout="24.20:31:23.6470000" receiveTimeout="24.20:31:23.6470000" sendTimeout="24.20:31:23.6470000">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession enabled="false" />
<security mode="None">
<message clientCredentialType="None" />
<transport protectionLevel="None" clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="False" />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
And here is the Silverlight client's ServiceReferences.ClientConfig file:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="NetTcpBinding_IVideoConferenceService">
<binaryMessageEncoding />
<tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost/Conference/VideoConferenceService.svc"
binding="customBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService"
contract="ServiceReference1.IVideoConferenceService" name="NetTcpBinding_IVideoConferenceService" />
</client>
</system.serviceModel>
</configuration>
Has anybody got any suggestions? This annoying error has taken days of my time thus far.
Any help would be greatly appreciated.
EDIT
When I check the files being retrieved in my web sessions using fiddler, it shows that my browser is retrieving the client access policy file, so I think the error lies somewhere else and WCF is just throwing this error at me? I've also set IE9 to clear its cache everytime its close. Take a look below.
Well I just managed to get it working. Couple of points worth mentioning are that:
1. If you look at the erroneous ServiceReferences.ClientConfig that I posted above (generated by visual studio when I gave the service address as: http://localhost/Conference/VideoConferenceService.svc ) you can see that the netTcp port which is 4502, was not generated as part of the endpoint, this is what what causing the TCP error 10016 (EndpointNotFoundException) as well as TCP error 10013. The correct ServiceReferences.ClientConfig is actually:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="NetTcpBinding_IVideoConferenceService">
<binaryMessageEncoding />
<tcpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:4502/Conference/VideoConferenceService.svc"
binding="customBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService"
contract="ServiceReference1.IVideoConferenceService" name="NetTcpBinding_IVideoConferenceService" />
</client>
</system.serviceModel>
</configuration>
2. When I was hosting my service in IIS 7, I was giving the port range 808:* as the netTcp ports, whereas I should have given 4502:* as the port range, like below:
Also from what I gathered, the website hosting the service should be on port 80, as Silverlight will look in localhost:80/ClientAccessPolicy.xml for the client access policy file.
And just for the record, for those who stumble across this same problem, this web.config managed to work in IIS:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="false" />
</system.web>
<system.serviceModel>
<services>
<service name="VideoServer.VideoConferenceService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IVideoConferenceService" contract="VideoServer.IVideoConferenceService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IVideoConferenceService" portSharingEnabled="false" transactionFlow="false" transferMode="Buffered" listenBacklog="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="24.20:31:23.6470000" openTimeout="24.20:31:23.6470000" receiveTimeout="24.20:31:23.6470000" sendTimeout="24.20:31:23.6470000">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession enabled="false" />
<security mode="None">
<message clientCredentialType="None" />
<transport protectionLevel="None" clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
Also worth noting that you don't need to put any ports or base addresses in the web.config for IIS. It will create the service endpoint using the port 4502, I tried changing it to 4503, 4522 etc. and interestingly it didn't work with those ports, only with 4502.
We had a similar problem as specified in the original post. Just to help anyone who has not been able to resolve the issue with the solutions provided above, we found that the Windows firewall on the machine hosting the service was blocking the port we were trying to connect with net.tcp through. Once we allowed the traffic through the port on that software firewall our service started working as expected.
It may be worth checking any hardware firewall you might have in place as well to allow the ranges 4502-4530 I believe for net.tcp
I have two applications that I want to test locally on the same machine. App 1 has a simple WCF service with the folloiwng config entry:
<service behaviorConfiguration="MyNamespace.ContainerManagementServiceBehavior"
name="MyNamespace.ContainerManagementService">
<endpoint address="ContainerManagementService" binding="basicHttpBinding"
name="ContainerManagementbasicHttpEndpoint"
contract="MyNamespace.IContainer" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/ContainerManagementService" />
</baseAddresses>
</host>
</service>
<behaviors>
<behavior name="MyNamespace.ContainerManagementServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</behaviors>
I start the service by running the web application project where it is hosted. I am able to successfully browse to the url and get web service information page from ie. I copy the same URL and use it for my client.
My other client, App 2, has the following in its config file:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttp" closeTimeout="00:10:00"
openTimeout="00:10:00" receiveTimeout="00:10:00"
sendTimeout="00:10:00" allowCookies="false"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard"
maxBufferSize="5242880" maxBufferPoolSize="524288"
maxReceivedMessageSize="5242880" messageEncoding="Text"
textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192"
maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="5242880" />
<security mode="None">
<transport clientCredentialType="None"
proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint
address="http://localhost:3227/Services/ContainerManagementService.svc"
binding="basicHttpBinding" bindingConfiguration="basicHttp"
contract="MyService.IService" name="externalService" />
</client>
</system.serviceModel>
However, when I try to execute a WCF call form client to the running service, I get the following error message:
There was no endpoint listening at
http://localhost:3227/Services/ContainerManagementService.svc
that could accept the message. This is often caused by an incorrect
address or SOAP action. See InnerException, if present, for more details.
What could be happening?
It looks likes the issue is due to the fact that both server and client are being run from the Cassini server. I am changing the architecture to host the server endpoint in IIS.
Do you have two applications ?
One which hosts the server endpoint and the other which is the client ? Are both active in IIS (considering the second application is a web app) ?
If you have two projects for those two components in your solution, you can configure VS to start both project at the same time. This way you can put breakpoints on both the client and the server and see if the server really gets called by the client or if the exception happens without the server method being called.
If your web service is on: http://localhost:8000/ContainerManagementService.svc
Your client app2 should point on this same addres:
<client>
<endpoint address="http://localhost:8000/ContainerManagementService.svc"
binding="basicHttpBinding" bindingConfiguration="basicHttp"
contract="MyService.IService" name="externalService" />
</client>
I have followed numerous msdn articles and the codeplex guidance but cannot get WCF to work with Kerberos authentication and delegation and would appreciate a little help.
Setup
I have the WCF service in an IIS website on a remote machine
IIS 6.0 on Windows 2003 R2 - SP 2
The SPN for the machine has been added (http/myserver && http/myserver:8080)
An AD account has been created for the IIS app pool
The AD account has the setting, allow delegation (for Kerberos), set to true
I am using Brian Booth's debug site on 8080 and the site passes all requirements for Kerberos delegation. The debug IIS site has anonymous authentication off, and Integrated Windows authentication on.
I have mirrored these settings to the site hosting the WCF service.
Web Service - Web Config (Original)
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WsHttpBindingConfig">
<security>
<message negotiateServiceCredential="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="Service">
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="WsHttpBindingConfig"
contract="IService">
<identity>
<servicePrincipalName value="http/myserver" />
<dns value="" />
</identity>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization
impersonateCallerForAllOperations="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Web Service - Web Method
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string GetCurrentUserName()
{
string name = WindowsIdentity.GetCurrent().Name;
return name;
}
Client App - App Config
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService"
... />
...
<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/Service.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService"
contract="KerberosService.IService"
name="WSHttpBinding_IService">
<identity>
<servicePrincipalName value="http/myserver" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Application Error
The following error occurs when my test application, a WinForms app, tries to call the web method:
"The HTTP request is unauthorized with
client authentication scheme
'Anonymous'. The authentication header
received from the server was
'Negotiate,NTLM'."
Event Log
The following error is in the event log:
Exception:
System.ServiceModel.ServiceActivationException:
The service '/Service.svc' cannot be
activated due to an exception during
compilation. The exception message
is: Security settings for this service
require 'Anonymous' Authentication but
it is not enabled for the IIS
application that hosts this service.
Which I don't understand. The whole point of this service is to not allow anonymous authentication, every user/request must be authenticated using Kerberos tickets, then passing them through to other machines.
How should I configure this WCF service for Kerberos authentication and delegation?
Revision 1
After reading this SO question I removed the metadata endpoint. This has not resolved the issue.
Revision 2
After more researching I found a few posts suggesting to change wsHttpBinding to basicHttpBinding. The modification to that portion of the web.config has been included below, and the service endpoint has been updated to refer to that binding.
Web Service - Web Config (Revised)
<basicHttpBinding>
<binding name="basicBindingConfig">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"
proxyCredentialType="Windows"
realm="" />
</security>
</binding>
</basicHttpBinding>
Client App - App Config (Revised)
<!-- ... -->
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"
proxyCredentialType="Windows"
realm="" />
<message clientCredentialType="UserName"
algorithmSuite="Default" />
</security>
<!-- ... -->
Error (Revised)
The current error looks like it contains a Kerberos authentication header.
The HTTP request is unauthorized with
client authentication scheme
'Negotiate'. The authentication header
received from the server was
'Negotiate SOMEHUGESCARYKEYHERE
For me the current setup does work:
On the Server:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBindingConf" useDefaultWebProxy="true"/>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="returnFaults" name="Epze.BusinessLayer.ZeitManager">
<endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpBindingConf" contract="Epze.Contract.IZeitManager"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="returnFaults">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization impersonateCallerForAllOperations="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Set the following attribute on all methods for the WCF:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
On the Client:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IZeitManager" 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>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="Delegation">
<clientCredentials>
<windows allowedImpersonationLevel="Delegation" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://server.mydomain.net/ePZEsvc/ZeitManager.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IZeitManager"
contract="External.Epze.IZeitManager" name="WSHttpBinding_IZeitManager" behaviorConfiguration="Delegation">
<identity>
<servicePrincipalName value="HOST/localhost"/>
</identity>
</endpoint>
</client>
</system.serviceModel>
HTH, Sven
Something that I notice: the client and server config don't seem to agree on security mode.
In the original section, you have <security>..... in the web.config (omitted the mode="message"), and <security mode="Message"> on the client side.
After your edit, it seems that the client side is unchanged, but the server (web.config) now contains <security mode="TransportCredentialOnly">.
The question really is: can you guarantee that there's only ever going to be one network leg between the client and the server being called? I.e. is this behind a corporate firewall? In that case, I would recommend netTcp binding with <security mode="Transport"> on both ends.
If that's not the case, then you're ok with either wsHttpBinding (which supports more security and reliability features, but is slower and "heavier") or basicHttpBinding. In that case, you would have to use <security mode="Message"> on both ends, and authenticate the service with a certificate (so that the service and client have a common "secret" which to use for encryption).
I would try to leave out the impersonation parts out for the beginning and just get the basic communication and mutual authentication between service and client up and running first - once that's in place, you can start adding the impersonation bits to it, and you can always fall back on a known configuration which works.
David Sackstein has a great series of blog posts explaining the five security scenarios that industry guru Juval Lowy has identified (in his Programming WCF book - the WCF Bible) as the most common and most useful - in order to limit the number of possible combinations of parameters you might want to tweak. One of them is a "Internet" scenario which would probably apply here, if your service is outward facing.
Marc
You need to specify a behaviorConfiguration in your client config. SVCUtil does not auto generate. This resolved my issue and I am now successfully using Kerberos. It was a mission though!
<client>
<endpoint address="..."
binding="customBinding" bindingConfiguration="..."
contract="..." name="..." behaviorConfiguration="ImpersonationBehavior" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="ImpersonationBehavior">
<clientCredentials>
<windows allowedImpersonationLevel="Impersonation"/> </clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
You should try your initial configuration and make sure to set the IIS to be anonymous and windows authentication at the same time.The reason is when you are using wsHttpBinding default security is message security and there is no transport security defined unless you want to do https. SO Clr states that it needs anonymous authentication turned-on on the IIS.
I am having an issue consuming a webservice (c#.net) from a WCF service.
The error i am getting is EndPointNotFoundException "TCP error code 10061: No connection could be made because the target machine actively refused it"
I wrote a unit test to check if i could send a request to the web service and it worked fine
[The unit test is using the same binding configuration as my WCF service]
The web service and WCF service (client) have basichttp binding.
Did anyone had similar kind of issue calling a webservice from a WCF service?
The service Model section is as follows
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="DataService" 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">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://10.22.33.67/Service/DataService.asmx" binding="basicHttpBinding"
bindingConfiguration="DataService" contract="Service.DataService" name="DataService"/>
</client>
<services>
<service name="TestToConsumeDataService.WCFHost.Service1" behaviorConfiguration="TestToConsumeDataService.WCFHost.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" contract="TestToConsumeDataService.WCFHost.IService1">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="TestToConsumeDataService.WCFHost.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>
The unit test project is also using the same service model section and it works. The only issue is while calling the service from another WCF service. Could you please suggest.
You mentioned "webservice" and "WCF service" - so the "webservice" is a old-style ASMX web service??
How is your WCF service hosted? In IIS? Do you have the necessary endpoint information for the webservice you're calling from WCF inside your web.config ??
Can you show us your relevant configs, e.g. the <system.serviceModel> section of your web.config (or app.config, if you're self-hosting the WCF service), please?
The error means there's either no webservice listening at the address you're using, or you don't have access rights to it. Are you missing some security or something?
MArc
It looks like there is some configuration that you need to call your web service.
This configuration is correct in the configuration file of your unit test.
But it is not correct or missing in the configuration file of your WCF service.
When you have two dll's where one calls the other, then it is the config file of the first dll that is used. However, when you go over a WCF hop, it is the config file of the WCF service that takes over.
Hope this helps
Shiraz
I'm trying to host a WCF Service with binding "wsDualHttpBinding". When I run my client and service(hosted in IIS) from the same machine it works fine. But, when I host the service in a different machine my client fails to register with the service. The following errors are coming...
[System.ServiceModel.Security.SecurityNegotiationEception]
The caller was not authenticated by
the service. And inner exception: The
request for security token could not
be satisfied because authentication
failed.
When trying to run from a different machine in another workgroup the following error appears
"Client is unable to finish the
security negotiation within the
configured time(00:00:00)"
In the IIS6.0 I turned off the Integrated Authentication and allowed anonymous access.
My Service's Web.Config follows:
<system.serviceModel>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"/>
</diagnostics>
<bindings>
<wsDualHttpBinding>
<binding name="StatTickerHttpBinding" bypassProxyOnLocal="false" useDefaultWebProxy="true" receiveTimeout="23:59:59">
<reliableSession ordered="true" inactivityTimeout="00:30:00"/>
</binding>
</wsDualHttpBinding>
</bindings>
<services>
<service name="StatTickerService" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="StatTickerHttpBinding" contract="IBroadCastService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
<identity>
<dns value="localhost"/>
</identity> -->
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- 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>
My Client App.Config follows...
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_StatTickerBroadcastService"
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:30:00"/>
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default"/>
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.100.77/TPS.StatTicker.WCFservice/Service.svc" binding="wsDualHttpBinding"
bindingConfiguration="WSDualHttpBinding_StatTickerBroadcastService"
contract="BroadcastGateway.StatTickerBroadcastService"
name="WSDualHttpBinding_StatTickerBroadcastService">
<identity>
<servicePrincipalName value="host/192.168.100.77"/>
</identity>
</endpoint>
</client>
</system.serviceModel>
The Client side config is done by using svcutil.
I searched and tried all the solutions given in the google for the past 4 days but no luck. Please help urgently.
If I understand your issue, it sounds like you're having problems with delegation.
Here's what I think you're trying to do:
User connects to web service
User authenticates with windows authentication (kerberos)
Webserver impersonates user
Webserver connects to backend via WCF
Webserver authenticates with backend using the user's credentials (kerberos)
Backend accepts credentials and serves up data
What needs to happen is your backend has to trust your web server to act on your behalf, called delegation. This is controlled by the domain and not freely given.
If both machines are on the same domain, the domain controller has to configure the web server as able to delegate for users. Without this, no machines on the network will trust your web server acting on a user's behalf. If this all takes place on the same machine, it does its own delegation.
If both machines are in a workgroup, I don't know what you would do.
I think you need to specify a security of "none" in the server's web.config. Otherwise it would default to insisting on an authentication mechanism.
Try this:
<identity>
<servicePrincipalName value=""/>
</identity>