I am learning WCF and i need to create a simple WCF service with a https binding. Need to have it as secure as possible.
So far i succeeded in creating a self-hosting wcf by using this guide:
Codeproject enable certificates on WCF
Managed to consume it, everything looks great. But the real problems appear when i try to host this in IIS 8. Local IIS, not IIS express.
I created a new wcf application in visual studio 2012, and in project's properties -> Web -> servers, i selected Local IIS, project URL: https://localhost/AdminService , Create virtual directory.
This added an application under Default Web Site in IIS Manager. The thing is, using the same web-config as my self-hosted app, roughly modified, did not work.
After altering it a bit, i got to this:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate"/>
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="WCFServiceCertificate.SecureServiceBehavior"
name="AdminService.AdminService">
<!--<host>
<baseAddresses>
<add baseAddress="https://localhost:1234/AdminService" />
</baseAddresses>
</host>-->
<endpoint address="https://localhost/AdminService" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"
contract="AdminServiceContract.IAdminService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
<!--<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />-->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFServiceCertificate.SecureServiceBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust" />
</clientCertificate>
<serviceCertificate findValue="CertAdminService" storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
That CertAdminService certificate was not created with makecert, like i did in the self-hosted wcf, but i created it with iis manager's "create self-signed certificate".
Then, on Default Web Site -> bindings, i added a new binding, https, and selected this certificate.
The problem is, even if i choose browse (*:443) on default web site, or my application, i get the following error:
Unable to make a secure connection to the server. This may be a problem with the server, or it may be requiring a client authentication certificate that you don't have.
Error code: ERR_SSL_PROTOCOL_ERROR
I have no idea what am i doing wrong. Also, having the mexHttpsBinding enabled, if i try to add service reference to another project, i can discover the service, but i get the following error:
"There was an error downloading 'https://localhost/AdminService/AdminService.svc/_vti_bin/ListData.svc/$metadata'.
The underlying connection was closed: An unexpected error occurred on a send.
The handshake failed due to an unexpected packet format.
Metadata contains a reference that cannot be resolved: 'https://localhost/AdminService/AdminService.svc'.
An error occurred while making the HTTP request to https://localhost/AdminService/AdminService.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.
The underlying connection was closed: An unexpected error occurred on a send.
The handshake failed due to an unexpected packet format.
If the service is defined in the current solution, try building the solution and adding the service reference again."
Any help will be much appreciated, i kind of ran out of ideas. According to other posts on stackoverflow that i've read, this should've work. Maybe i'm doing something wrong and i don't know what.
Thank you, and sorry for the long post.
Edit:
Here is the consuming client's web.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IAdminService">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate" />
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost/AdminService"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IAdminService"
contract="AdminServiceContract.IAdminService" name="WSHttpBinding_IAdminService" behaviorConfiguration="CustomBehavior">
<identity>
<dns value="WCfServer" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior">
<clientCredentials>
<clientCertificate findValue="CertAdminService" x509FindType="FindBySubjectName"
storeLocation="LocalMachine" storeName="My" />
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Related
I have developed WCF windows service using net tcp binding. Its working fine when wcf client and wcf service both are in domain (in two different system)
Getting error when both system are in work group not in domain.
Throwing an exception. Source: System.ServiceModel 4.0.0.0. Exception details: System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '04:59:59.7955781'. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
Things I tried:
Turned off Firewalls
Checked port
Increased the timeouts
First, you need to add windows credentials when requesting because nettcpbinding defaults to windows authentication:
ServiceReference1.CalculatorClient calculatorClient = new ServiceReference1.CalculatorClient();
calculatorClient.ClientCredentials.Windows.ClientCredential.UserName = "Administrator";
calculatorClient.ClientCredentials.Windows.ClientCredential.Password = "Password";
If you still have problems after adding credentials, you also need to add a mex endpoint:
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange"></endpoint>
This is my App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<system.serviceModel>
<services>
<service name="ConsoleApp5.CalculatorService" behaviorConfiguration="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:10234/GettingStarted/"/>
</baseAddresses>
</host>
<endpoint address="Test"
binding="netTcpBinding"
contract="ConsoleApp5.ICalculator"/>
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
UPDATE
Set the Mode value to Message:
<binding name="Binding">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
This is my App.config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.Samples.X509CertificateValidator.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior">
<!-- use host/baseAddresses to configure base address provided by host -->
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8001/servicemodelsamples/service"/>
</baseAddresses>
</host>
<!-- use base address specified above, provide one endpoint -->
<endpoint address="certificate" binding="netTcpBinding" bindingConfiguration="Binding" contract="Microsoft.Samples.X509CertificateValidator.ICalculator"/>
</service>
</services>
<bindings>
<netTcpBinding>
<!-- X509 certificate binding -->
<binding name="Binding">
<security mode="Message">
<message clientCredentialType="Certificate" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata/>
<serviceCredentials>
<!--
The serviceCredentials behavior allows one to specify authentication constraints on client certificates.
-->
<clientCertificate>
<authentication certificateValidationMode="None" revocationMode="NoCheck"/>
</clientCertificate>
<!--
The serviceCredentials behavior allows one to define a service certificate.
A service certificate is used by a client to authenticate the service and provide message protection.
This configuration references the "localhost" certificate installed during the setup instructions.
-->
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
Feel free to let me know if the problem persists.
I am trying to add transport security layer to my WCF service. But after following all the instructions i still get error "Could not find a base address that matches scheme https for the endpoint with binding BasicHttpBinding. Registered base address schemes are [http]."
Already did all needed configurations in IIS Manager and add need code in web.config but i still have a feeling i am missing something
web.config:
<system.serviceModel>
<services>
<service name="MyNameSpace.MyService" behaviorConfiguration="secureBehavior">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="secureHttpBinding" contract="MyNameSpace.IMyService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="secureBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
There is no problem with your present configuration, configure an https endpoint and it uses Transport security mode. One more thing we need to do is configuring an https binding address in IIS binding module. Like below.
It locates in the IIS site binding module.
Then we could use the above https service address to access it.
https://IP:4431/Service1.svc (service base address)
Feel free to let me know if the problem still exists.
I created a simple WCF service and hosted it in IIS by creating a new website. In Web.config file,I am providing bindings for http and net tcp.
I created a console client and adding service reference. It generates two binding in client config - for http and for tcp. When I try to invoke the service using tcp, I get this error -
An unhandled exception of type 'System.ServiceModel.EndpointNotFoundException' occurred in mscorlib.dll
Additional information: There was no endpoint listening at net.tcp://computername/Service.svc that could accept the message. This is often caused by an incorrect address or SOAP action.
when I run using Http endpoint , it works fine.
Note -
I am using Windows 10 OS, IIS 10.0 and WPAS\WAS (Windows Process Activation Service) are installed. I already enabled\checked HTTP Activation, TCP Activation in .Net framework in Windows features. And modified IIS server settings to include net tcp. Please check it in attached image.
My website Web.config file looks like
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NewBinding0" portSharingEnabled="true">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service behaviorConfiguration="My" name="WCFServiceOM.Service1"> <!-- the service name must match the configuration name for the service implementation. -->
<endpoint address="" binding="basicHttpBinding" contract="WCFServiceOM.IService1"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<endpoint binding="netTcpBinding" bindingConfiguration="NewBinding0" contract="WCFServiceOM.IService1" />
<endpoint address="mexOM" binding="mexTcpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8087/Service1" />
<add baseAddress="http://localhost:7777/Service1"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webBehanior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="My">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="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="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
And my client App.Config look like
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
<netTcpBinding>
<binding name="NetTcpBinding_IService1">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="http://computername:7777/Service.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
<endpoint address="net.tcp://computername/Service.svc" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IService1" contract="ServiceReference1.IService1"
name="NetTcpBinding_IService1" />
</client>
</system.serviceModel>
I made a WCF Service: HelloWorldService follow tips in Implement HelloWorld Service then hosted in IIS 8.5 (Windows 8.1) with Basic Authentication
and my web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment >
<serviceActivations>
<add factory="System.ServiceModel.Activation.ServiceHostFactory"
relativeAddress="./HelloWorldService.svc"
service="MyWCFServices.HelloWorldService"/>
</serviceActivations>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="MyWCFServices.HelloWorldService">
<endpoint address="" binding="basicHttpBinding"
contract="MyWCFServices.IHelloWorldService"
bindingConfiguration="secureHttpBinding">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name ="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
I publish successful in try in Browser and Login with my username and password. It worked
But Error when I add service refercence, I cann't this with same my username and password on VS2013.
I try many times with username and password but I return dialog again
and I must click No.
This is Details:
There was an error downloading
https://localho.st/HelloWorldSecure/HelloWorldService.svc/_vti_bin/ListData.svc/$metadata
The request failed with HTTP status 400: Bad Request. Metadata
contains a reference that cannot be resolved:
https://localho.st/HelloWorldSecure/HelloWorldService.svc The
HTTP request is unauthorized with client authentication scheme
'Anonymous'. The authentication header received from the server was
'Basic realm=mylocalhost'. The remote server returned an error: (401)
Unauthorized. If the service is defined in the current solution, try
building the solution and adding the service reference again.
Somebody help me make it correctly. Many thanks!
I already asked a similar question here: Unable to add service client for a net.tcp WCF service. The problem was solved at that time. But now the same error is coming up. My configuration of WCF service is same as that of previous question. I am again posting it here:
<system.serviceModel>
<services>
<service name="CoreService.Service1" behaviorConfiguration="beh1">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost/Service1.svc/mex" />
</baseAddresses>
</host>
<endpoint
binding="netTcpBinding"
bindingConfiguration="ultra"
contract="CoreService.IAccountService"/>
<endpoint
binding="netTcpBinding"
bindingConfiguration="ultra"
contract="CoreService.IBoardService"/>
<endpoint
binding="netTcpBinding"
bindingConfiguration="ultra"
contract="CoreService.ICategoryService"/>
<endpoint
address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="ultra"
maxBufferPoolSize="2147483647"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647"
portSharingEnabled="false"
transactionFlow="false"
listenBacklog="2147483647"
sendTimeout="00:01:00">
<security mode="None">
<message clientCredentialType="None"/>
<transport protectionLevel="None" clientCredentialType="None"/>
</security>
<reliableSession enabled="false"/>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="beh1">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="True" />
<dataContractSerializer maxItemsInObjectGraph="65536" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
The error is:
The URI prefix is not recognized. Metadata contains a reference that
cannot be resolved: 'net.tcp://localhost/Service1.svc'. Could not
connect to net.tcp://localhost/Service1.svc. The connection attempt
lasted for a time span of 00:00:02.0051147. TCP error code 10061: No
connection could be made because the target machine actively refused
it 127.0.0.1:808. No connection could be made because the target
machine actively refused it 127.0.0.1:808 If the service is defined in
the current solution, try building the solution and adding the service
reference again.
After the problem was solved, I didn't made any changes to the configuration and after some days it started showing that error again. I tried everything but nothing worked. Please help!
UPDATE: I am also able to access it using HTTP through my browser but unable to access using "Add Service Reference" option through net.tcp protocol.
Finally with the help of this link: http://rohitguptablog.wordpress.com/2011/06/16/configuring-wcf-service-with-nettcpbinding/, I figured out what was going wrong. Actually I missed the third step in above link. The Net.Tcp services were not running.