Самостоятельная командная строка WCF возвращает ошибку 503

Надеюсь, что вы сможете мне помочь!

У меня есть собственная командная строка WCF через https с сертификатом X509, и я всегда получаю сообщение об ошибке Http 503. В настоящее время ОС Windows 8.1 с VS Community 2015. В конце эта командная строка будет интегрирована в службу Windows...

Мой код C# для службы WCF:

using System;
using System.ServiceModel;
using WCF_Service_Library; //Contract and operations are defined in this library
using System.Threading;
using System.Globalization;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel.Description;
using System.Net;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Reflection;

namespace Service_Commandline
{
    class Program
    {
        static void Main(string[] args)
        {               
            ServiceHost serviceHost;

            //Get base Url for Web Service WCF
            string addressHttps;
            string CurrentDnsHostName = Dns.GetHostEntry("").HostName;

            addressHttps = String.Format("https://" +CurrentDnsHostName + ":443");

            BasicHttpBinding wsHttpBinding =new BasicHttpBinding();
            wsHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;

            serviceHost = new ServiceHost(typeof(PCsService), new Uri(addressHttps));

            //Add service endpoint
            Type endpoint = typeof(IPCsService);

            serviceHost.AddServiceEndpoint(endpoint, wsHttpBinding, "WCF");

            //Search for X509 certificate
            X509Certificate2 certFound = FindX509Certificate("server");

            if (certFound!=null)
                serviceHost.Credentials.ServiceCertificate.Certificate=certFound;

            serviceHost.Credentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;

            Uri uri = new Uri(serviceHost.Description.Endpoints[0].ListenUri.AbsoluteUri + "/mex");

            //Add a behavior linked to Mex endpoint
            ServiceMetadataBehavior 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);
                //Certificate is:
                Assembly assembly = typeof(Program).Assembly;
                GuidAttribute attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
                string appIdInString = attribute.Value;
                Console.WriteLine("AppId is: " + appIdInString);
                if (certFound != null)
                {
                    Console.WriteLine("Certificate is: " + certFound.FriendlyName);
                    Console.WriteLine("Certificate thumbprint is: " + certFound.Thumbprint);
                }
                else
                {
                    Console.WriteLine("No certificate used...");
                }
                Console.WriteLine("Press enter to close the service");
                Console.ReadLine();

            }
            catch (CommunicationException ce)
            {
                Console.WriteLine("A commmunication error occurred: {0}", ce.Message);
                Console.WriteLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine("An unforseen error occurred: {0}", ex.Message);
                Console.ReadLine();
            }
            finally
            {
                //Close WCF service whatever error found
                if (serviceHost != null && serviceHost.State!=CommunicationState.Closed)
                    serviceHost.Close();
            }
        }

        private static X509Certificate2 FindX509Certificate(string wCFServerName, StoreName storeName=StoreName.My, StoreLocation storeLocation=StoreLocation.LocalMachine)
        {
            //Find valid certificate
            X509Certificate2Collection searchForCurrentServerCertificate = new X509Certificate2Collection();
            X509Certificate2 certFound = new X509Certificate2();
            X509Store store=null;

            try
            {
                store = new X509Store(storeName, storeLocation);

                store.Open(OpenFlags.ReadOnly);
                searchForCurrentServerCertificate = store.Certificates.Find(X509FindType.FindBySubjectName, wCFServerName, true);

                certFound = null;
                if (searchForCurrentServerCertificate != null && searchForCurrentServerCertificate.Count > 0)
                {
                    certFound = searchForCurrentServerCertificate[0];
                }
                store.Close();
            }
            catch (Exception)
            {

                if (store != null)
                    store.Close();
            }

            return certFound;
        }
    }
}

Вывод этого кода C#:

Mex address  https:// dev01/WCF/mex
Listening @ https:// dev01/WCF
AppId is: f8939c9f-46e7-4d85-ba57-045e68e7fe44
Certificate is: Certificate for this app on port 443
Certificate thumbprint is: 5A26F1C44DE99C0FEB3FB89C80664B9619211696
Press enter to close the service

Я также зарезервировал пространство имен с помощью cmd:

netsh http add urlacl url= https:// +:443/WCF/ user="\Everyone"

И присоедините сертификат X509 к порту 443 с помощью cmd:

netsh http add sslcert ipport=0.0.0.0:443 certhash=5a26f1c44de99c0feb3fb89c80664b9619211696 appid={f8939c9f-46e7-4d85-ba57-045e68e7fe44} certstorename=MY

Наконец, эти 2 командные строки выглядят хорошо в соответствии с этими выводами:

C:\Windows\system32>netsh http show urlacl url=https:// +:443/WCF/

Réservations d'URL :
--------------------

    URL reserved            : https:// +:443/WCF/
        Utilisateur : \Everyone
            Écouter : Yes
            Déléguer : No
            SDDL : D:(A;;GX;;;WD)

C:\Windows\system32>netsh http show sslcert ipport=0.0.0.0:443

Liaisons de certificat SSL :
----------------------------

    Adresse IP:port                      : 0.0.0.0:443
    Hachage du certificat             : 5a26f1c44de99c0feb3fb89c80664b9619211696

    ID de l'application               : {f8939c9f-46e7-4d85-ba57-045e68e7fe44}
    Nom du magasin de certificats :       : (null)
    Vérifier la révocation des certificats clients : Enabled
    Vérifier la révocation au moyen du certificat client mis en cache uniquement
 : Disabled
    Vérification de l'utilisation                  : Enabled
    Heure d'actualisation de la révocation    : 0
    Délai d'attente de la récupération d'URL        : 0
    Identificateur CTL               : (null)
    Nom du magasin CTL               : (null)
    Utilisation du mappeur DS              : Disabled
    Négocier le certificat client : Disabled

И у меня нет другого зарезервированного URL на https:/WCF/.

Что бы я ни пытался, я получаю ошибку 503 на https:// DEV01:443/WCF/. Но конечная точка mex, кажется, в порядке на https:// DEV01:443/WCF/Mex. Я получаю результат в формате XML. В mex Xml мне кажется странным только одно: targetNamespace в конечной точке mex равно http: // tempuri.org/.

Пожалуйста, помогите мне в этом вопросе!

С уважением, Франсуа

1 ответ

Решение

Наконец-то я нашел способ заставить эту Самостоятельную Службу работать. Я больше не использую параметры в коде. Я использую app.config, который определил 99% моей конфигурации serviceHost, и просто добавляю часть кода в код (например, управление сертификатами).

Насколько я знаю, этот пример имел 0 шансов на такую ​​работу! Многие ребята объясняют обратное, но они были неправы.

Итак, с app.config мой код довольно прост:

static void Main(string[] args)
    {               
        ServiceHost serviceHost;

        serviceHost = new ServiceHost(typeof(PCsService));

        try
        {
            serviceHost.Open();
            ...
            ...

Надеюсь, это поможет кому-то еще!

С уважением.

Другие вопросы по тегам