WCF, HTTPS по сравнению с HTTP

Существует два образца

Для 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
    }
}

Для 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
    }
}

Эти образцы запускаются без ошибок, но если я пытаюсь создать клиенты, у меня есть две различных ситуации:

HTTP - клиент был создан успешный адрес использования

http://localhost:51222/hello/mex

И HTTPS перестал работать. Адрес для HTTPS:

https://localhost:51222/hello/mex

Сообщение об ошибке для HTTPS:

Была ошибка при загрузке https://localhost:51222/hello/mex. Базовое соединение было закрыто: неожиданная ошибка произошла на отправлении. Аутентификация перестала работать, потому что удаленная сторона закрыла транспортный поток. Метаданные содержат ссылку, которая не может быть разрешена: https://localhost:51222/hello/mex. Ошибка произошла при создании Запроса HTTP к https://localhost:51222/hello/mex. Это могло быть то, вследствие того, что сертификат сервера не настроен правильно с HTTP.SYS в случае HTTPS. Это могло также быть вызвано несоответствием привязки безопасности между клиентом и сервером. Базовое соединение было закрыто: неожиданная ошибка произошла на отправлении. Аутентификация перестала работать, потому что удаленная сторона закрыла транспортный поток. Если сервис определяется в текущем решении, попытайтесь создать решение и добавить сервисную ссылку снова.

Где я делал ошибку?

8
задан Peter Mortensen 31 August 2013 в 08:57
поделиться

2 ответа

Я нашел решение, как решить эту проблему. Итак, правильный код сервера:

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

И несколько случаев, связанных с сертификатом: - создание сертификата:

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
  • добавление URL для прослушивания

    httpcfg set urlacl -u https: // *: 9010 / -a D: (A ;; GX ;;; S-1-5-21-1144070942-1563683482 -3278297161-1114)

  • скажите http.sys, чтобы узнать о сертификате ssl на порту 9010

    httpcfg set ssl / i 0.0.0.0:9010 / h 8c6e12be5371860adfb84cd2ed2351a900731bb8 / g "{a2c24c83-8ed0ef- -d93836fec137} "

    И все работает без проблем.

8
ответ дан 5 December 2019 в 18:56
поделиться

Может быть, вы делаете httpsGetUri таким же, как адрес конечной точки mex? httpsGetUri предназначен для публикации WSDL, а не для обслуживания конечных точек mex. Вам следует прояснить этот вопрос.

0
ответ дан 5 December 2019 в 18:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: