Служба WCF через HTTPS без IIS, с сертификатом SSL из строк или файлов CERT и KEY - PullRequest
0 голосов
/ 17 февраля 2019

Я уже работал с WCF - но так как он был только для внутреннего использования, вообще недоступен из Интернета, я просто использовал net.tcp и не особо заботился о безопасности.

Однако сейчас я готовлюсь к проекту, который будет доступен клиентам через Интернет, поэтому необходимо планировать безопасность.

Я провел некоторое исследование по этому вопросу, и из чегоя понял (поправьте меня, если я ошибаюсь здесь), HTTPS - моя лучшая ставка, поскольку HTTP вообще не защищен (по умолчанию), и net.tcp может найти проблемы с некоторыми брандмауэрами.

ХауэреЯ не хочу заставлять клиентов устанавливать IIS на своих серверах, если они этого не хотят, поэтому мы планируем использовать службу Windows, размещенную самостоятельно.Тем не менее, я не могу найти какую-либо информацию о том, как настроить сервер для использования HTTPS без IIS.

  1. Я нашел информацию об использовании makecert и httpcfg set ssl для добавленияновый сертификат в магазине, а затем установить его в порт - это нормально для тестирования, но я не вижу этого выполнимым на сервере клиента - не говоря уже о том, что я буду использовать самозаверяющий сертификат - снова хорошо для тестирования,не так много в производстве

  2. Я также нашел информацию ( ServiceCredentials MSDN page ) об использовании чего-то вроде

    sh.Credentials.ServiceCertificate.SetCertificate(
        StoreLocation.LocalMachine, StoreName.My,
        X509FindType.FindByThumbprint, 
        "af1f50b20cd413ed9cd00c315bbb6dc1c08da5e6");
    

для установки сертификата, который уже находится в хранилище сертификатов сервера - это было бы почти нормально - для этого все же требуется, чтобы клиент знал, как управлять сертификатами в хранилище, не идеально, но нормально.Однако я не мог заставить его работать - я не получаю никакой ошибки при запуске службы, но если я пытаюсь перейти на адрес службы в браузере, я получаю ошибку, касающуюся устаревания TLS - Q1: Любая идея, чтоможет быть проблема здесь?

Q2: возможно ли иметь конфигурацию где-нибудь, где клиент мог бы ввести имеющийся или, по крайней мере, местоположение для файлов сертификата и ключа, получаемых при покупке сертификата, и использовать их для защитыуслуга?

1 Ответ

0 голосов
/ 18 февраля 2019

Q1: Как указано в ошибках, в вашем сертификате может быть проблема.убедитесь, что сертификат действителен (самоподписанный сертификат не может устареть).
Q2: Насколько мне известно, мы могли бы сохранить сертификат в виде файла (pfx, cert) или установить сертификат в хранилище сертификатов (certlm.msc, certmgr.msc) для управления.
Хотите разместить службу WCF через https в проекте службы Windows?Я сделал демо, желаю, чтобы это было полезно для вас.
Service1.cs

public partial class Service1 : ServiceBase
        {
            public Service1()
            {
                InitializeComponent();
            }
            Uri uri = new Uri("https://localhost:1017");
            ServiceHost sh = null;
            protected override void OnStart(string[] args)
            {
                BasicHttpBinding binding = new BasicHttpBinding();
                binding.Security.Mode = BasicHttpSecurityMode.Transport;
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
                try
                {
                    ServiceHost sh = new ServiceHost(typeof(MyService), uri);
                    sh.AddServiceEndpoint(typeof(IService), binding, "");
                    ServiceMetadataBehavior smb;
                    smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
                    if (smb == null)
                    {
                        smb = new ServiceMetadataBehavior()
                        {
                            HttpsGetEnabled=true,
                        };
                        sh.Description.Behaviors.Add(smb);
                    }
                    Binding mexbinding = MetadataExchangeBindings.CreateMexHttpsBinding();
                    sh.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");
                    sh.Open();
                    WriteLog($"Service is ready at {DateTime.Now.ToString("hh-mm-ss")}");
                }
                catch (Exception e)
                {
                    WriteLog(e.ToString());
                    throw;
                }
            }

            protected override void OnStop()
            {
                if (sh!=null&&sh.State==CommunicationState.Opened)
                {
                    sh.Close();
                    WriteLog($"Service is closed at {DateTime.Now.ToString("hh-mm-ss")}");
                }
            }

            public static void WriteLog(string text)
            {
                using (StreamWriter sw = File.AppendText(@"C:\Mylog.txt"))
                {
                    sw.WriteLine(text);
                    sw.Flush();
                }
            }
        }
        [ServiceContract(Namespace = "mydomain")]
        public interface IService
        {
            [OperationContract]
            string SayHello();
        }
        public class MyService : IService
        {
            public string SayHello()
            {
                Service1.WriteLog(string.Format("Wow, I have been called at {0}", DateTime.Now.ToString("hh-mm-ss")));
                return "Hello stranger";
            }
    }

ProjectInstaller.cs
enter image description here
enter image description here
Установка службы Windows (CMD с правами администратора)
enter image description here
Привязать сертификат к порту приложения.
enter image description here
https://docs.microsoft.com/en-us/windows/desktop/http/add-sslcert
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-a-port-with-an-ssl-certificate
Параметр Certhash указывает отпечаток большого пальцасертификат.Параметр appid - это GUID, который можно использовать для идентификации владельца приложения (откройте файл project.csproj)

<ProjectGuid>{56FDE5B9-3821-49DB-82D3-9DCE376D950A}</ProjectGuid>

Запустите службу Windows.
enter image description here
Тест (IP-адрес сервера 10.157.13.70):
enter image description here
Вызов клиента (имеетсяшаг, который проверяет сертификат сервера по умолчанию)

static void Main(string[] args)
    {
        ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
        ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
        try
        {
            var result = client.SayHello();
            Console.WriteLine(result);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

Результат
enter image description here
Не стесняйтесьдайте мне знать, если я могу чем-то помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...