There are two samples
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
string addressHttps = String.Format("http://{0}:51222", Dns.GetHostEntry("").HostName);
var wsHttpBinding = new BasicHttpBinding();
var serviceHost = new ServiceHost(typeof (HelloWorldService), new Uri(addressHttps));
Type endpoint = typeof (IHelloWorldService);
serviceHost.AddServiceEndpoint(endpoint, wsHttpBinding, "hello");
Uri uri = new Uri(serviceHost.Description.Endpoints[0].ListenUri.AbsoluteUri + "/mex");
var smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.HttpGetUrl = uri;
serviceHost.Description.Behaviors.Add(smb);
Console.Out.WriteLine("Mex address " + smb.HttpGetUrl);
try
{
serviceHost.Open();
string address = serviceHost.Description.Endpoints[0].ListenUri.AbsoluteUri;
Console.WriteLine("Listening @ {0}", address);
Console.WriteLine("Press enter to close the service");
Console.ReadLine();
serviceHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("A commmunication error occurred: {0}", ce.Message);
Console.WriteLine();
}
catch (Exception exc)
{
Console.WriteLine("An unforseen error occurred: {0}", exc.Message);
Console.ReadLine();
}
}
}
[ServiceContract]
public interface IHelloWorldService
{
[OperationContract]
string SayHello(string name);
}
public class HelloWorldService : IHelloWorldService
{
#region IHelloWorldService Members
public string SayHello(string name)
{
return string.Format("Hello, {0}", name);
}
#endregion
}
}
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
string addressHttps = String.Format("https://{0}:51222", Dns.GetHostEntry("").HostName);
var wsHttpBinding = new BasicHttpBinding();
wsHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
var serviceHost = new ServiceHost(typeof (HelloWorldService), new Uri(addressHttps));
Type endpoint = typeof (IHelloWorldService);
serviceHost.AddServiceEndpoint(endpoint, wsHttpBinding, "hello");
serviceHost.Credentials.ServiceCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindBySubjectName, "nameofsertificate");
serviceHost.Credentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
Uri uri = new Uri(serviceHost.Description.Endpoints[0].ListenUri.AbsoluteUri + "/mex");
var smb = new ServiceMetadataBehavior();
smb.HttpsGetEnabled = true;
smb.HttpsGetUrl = uri;
serviceHost.Description.Behaviors.Add(smb);
Console.Out.WriteLine("Mex address " + smb.HttpsGetUrl);
try
{
serviceHost.Open();
string address = serviceHost.Description.Endpoints[0].ListenUri.AbsoluteUri;
Console.WriteLine("Listening @ {0}", address);
Console.WriteLine("Press enter to close the service");
Console.ReadLine();
serviceHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("A commmunication error occurred: {0}", ce.Message);
Console.WriteLine();
}
catch (Exception exc)
{
Console.WriteLine("An unforseen error occurred: {0}", exc.Message);
Console.ReadLine();
}
}
public static bool ValidateCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors)
{
foreach (X509ChainStatus chainStatus in chain.ChainStatus)
{
if (chainStatus.Status == X509ChainStatusFlags.Revoked)
{
return true;
}
}
}
return false;
}
}
[ServiceContract]
public interface IHelloWorldService
{
[OperationContract]
string SayHello(string name);
}
public class HelloWorldService : IHelloWorldService
{
#region IHelloWorldService Members
public string SayHello(string name)
{
return string.Format("Hello, {0}", name);
}
#endregion
}
}
These samples are starting without errors, but if I try to create clients I have two different situations:
HTTP - the client was created successful using address
http://localhost:51222/hello/mex
And HTTPS failed. The address for HTTPS is:
https://localhost:51222/hello/mex
The error message for HTTPS is:
There was an error downloading
https://localhost:51222/hello/mex
. The underlying connection was closed: An unexpected error occurred on a send. Authentication failed because the remote party has closed the transport stream. Metadata contains a reference that cannot be resolved:https://localhost:51222/hello/mex
. An error occurred while making the HTTP request tohttps://localhost:51222/hello/mex
. 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. Authentication failed because the remote party has closed the transport stream. If the service is defined in the current solution, try building the solution and adding the service reference again.
Where did I make a mistake?
In IIS 7.5, go to your site and click on Bindings under Edit Site Action. Ensure that both http & https have been added. Then you need to create a binding for HTTP under <basicHttpBinding> , with security mode set to none. Add the newly created binding configuration to http endpoint.
The protocols that are typically used in this channel are HTTP, TCP, MSMQ, and named pipes, but WCF allows application developers to use other transports as well, such as Simple Mail Transfer Protocol (SMTP) or File Transfer Protocol (FTP).
I found solution how to decided this problem. So, the correct code of server is:
using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
string addressHttps = String.Format("https://{0}:9010", Dns.GetHostEntry("").HostName);
var wsHttpBinding = new BasicHttpBinding();
wsHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
var serviceHost = new ServiceHost(typeof (HelloWorldService), new Uri(addressHttps));
Type endpoint = typeof (IHelloWorldService);
serviceHost.AddServiceEndpoint(endpoint, wsHttpBinding, "hello");
serviceHost.Credentials.ServiceCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindBySubjectName, "sergiiz2");
var smb = new ServiceMetadataBehavior();
smb.HttpsGetEnabled = true;
smb.HttpsGetUrl = new Uri(serviceHost.Description.Endpoints[0].ListenUri.AbsoluteUri + "/mex");
serviceHost.Description.Behaviors.Add(smb);
Console.Out.WriteLine(smb.HttpsGetUrl);
try
{
serviceHost.Open();
string address = serviceHost.Description.Endpoints[0].ListenUri.AbsoluteUri;
Console.WriteLine("Listening @ {0}", address);
Console.WriteLine("Press enter to close the service");
Console.ReadLine();
serviceHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("A commmunication error occurred: {0}", ce.Message);
Console.WriteLine();
}
catch (Exception exc)
{
Console.WriteLine("An unforseen error occurred: {0}", exc.Message);
Console.ReadLine();
}
}
}
[ServiceContract]
public interface IHelloWorldService
{
[OperationContract]
string SayHello(string name);
}
public class HelloWorldService : IHelloWorldService
{
#region IHelloWorldService Members
public string SayHello(string name)
{
return string.Format("Hello, {0}", name);
}
#endregion
}
}
And a few cases related to certificate: - generating certificate:
makecert -r -pe -n "CN=%hostname%" -b 01/01/2000 -e 01/01/2050 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
adding url to listening
httpcfg set urlacl -u https://*:9010/ -a D:(A;;GX;;;S-1-5-21-1144070942-1563683482-3278297161-1114)
say to the http.sys to know about ssl certificate on the port 9010
httpcfg set ssl /i 0.0.0.0:9010 /h 8c6e12be5371860adfb84cd2ed2351a900731bb8 /g "{a2c24c79-b0ef-4783-8ed8-d93836fec137}"
And all works without problems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With