2016-06-20 10 views
0

당신이 나를 도울 수 있기를 바랍니다!WCF 자체 호스팅 명령 줄 반환 503 오류

나는 X509 인증서가있는 https를 통해 자체 호스팅 WCF 명령 행을 가지고 있으며 항상 HTTP 503 오류가 발생합니다. 이것의

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

출력 : OS는

WCF 서비스에 대한 내 C# 코드가이 중 하나입니다 ...이 명령 줄은 Windows 서비스에 통합 될 말 현재 VS 커뮤니티 2015 년에 윈도우 8.1 C# 코드는 다음과 같습니다

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

그리고에서 : 나는 또한 cmd를 함께 네임 스페이스를 예약 한

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를 가진 포트 443에 타코미터 X509 인증서 :

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 

그리고 https://...443:/WCF/ 다른 예약 된 URL이 없습니다 :

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

마지막으로,이 2 commandlines은 이러한 출력에 따라 확인을 보인다.

무엇을 시도해도 https : // DEV01 : 443/WCF /에서 503 오류가 발생합니다. 하지만 mex 엔드 포인트는 https : // DEV01 : 443/WCF/Mex에서 정상인 것 같습니다. 나는 Xml 결과를 얻는다. 한 가지만 mex Xml에서 나를 이상하게 보입니다. targetNamespace는 mex 끝 점이 "http : // tempuri.org/"와 동일합니다.

이 주제에 대한 도와주세요. 나는 마침내 방법을 발견 프랑수아

+0

사용 된 X509 인증서가 CA에서 제공하고 그 호스트 이름 (CN = XXXXX.XXXXX.fr)이 내 dev 호스트 이름과 일치하지 않는다고 말할 수 있습니다 ... 문제가있을 수 있습니까? – Francois

+0

makecert.exe로 개인 인증서를 만들었지 만 여전히 503 오류가 있습니다 ... – Francois

답변

0

감사합니다,이 자체 호스팅 서비스가 작동해야합니다. 코드에서 더 이상 매개 변수를 사용하지 않습니다. 내 serviceHost 구성의 99 %를 정의한 app.config를 사용하고 인증서 관리와 같은 일부 매개 변수를 코드에 추가합니다.

내가 아는 한이 예제는 그런 식으로 작동 할 가능성이 0입니다! 많은 사람들이 반대 의견을 설명하지만 잘못되었습니다.

그래서,의 app.config에, 내 코드는 매우 간단합니다 :

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

     serviceHost = new ServiceHost(typeof(PCsService)); 

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

이 다른 사람을 도움이 될 것입니다 희망!

감사합니다.