tags:

views:

163

answers:

2

Hello, There are two samples: for http:

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
    }
}

and for https:

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 - client was created successful using address

http://localhost:51222/hello/mex

and https is failed 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 to https://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. Could you help me and answer where I did a mistake :( ?

A: 

Could it be that you're making the httpsGetUri the same as your mex endpoint address? httpsGetUri is for publishing the WSDL, not servicing mex endpoints. You should clear that up.

tomasr
The http example the same, but works successful.
jitm
A: 

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.

jitm