WCF 自承载命令行 return 503 错误
WCF Self-hosted Commandline return 503 error
希望您能帮到我!
我有一个通过 https 和 X509 证书的自托管 WCF 命令行,但我总是收到 Http 503 错误。 OS 目前是 Windows 8.1 with VS Community 2015。最后,此命令行将集成到 Windows 服务中...
我的 WCF 服务 C# 代码是这个:
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"
并使用 cmd 将 X509 证书附加到端口 443:
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
而且我在 https://...443:/WCF/ 上没有其他保留 Url。
无论我尝试什么,我都会在 https:// DEV01:443/WCF/ 上收到 503 错误。
但是mex端点在https://DEV01:443/WCF/Mex上好像没问题。
我得到 Xml 结果。在 mex Xml 中,只有一件事对我来说似乎很奇怪:targetNamespace 在 mex 端点中等于 "http:// tempuri.org/"。
请帮我解决这个问题!
此致,
弗朗索瓦
我终于找到了让这个自托管服务正常工作的方法。
我不再在代码中使用参数。
我使用 app.config 定义了 99% 的 serviceHost 配置,并在代码中添加了一些参数(如证书管理)。
据我所知,这个例子有 0 次这样的机会!
很多人解释相反,但他们错了。
所以,有了app.config,我的代码就很简单了:
static void Main(string[] args)
{
ServiceHost serviceHost;
serviceHost = new ServiceHost(typeof(PCsService));
try
{
serviceHost.Open();
...
...
希望对其他人有所帮助!
此致。
希望您能帮到我!
我有一个通过 https 和 X509 证书的自托管 WCF 命令行,但我总是收到 Http 503 错误。 OS 目前是 Windows 8.1 with VS Community 2015。最后,此命令行将集成到 Windows 服务中...
我的 WCF 服务 C# 代码是这个:
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"
并使用 cmd 将 X509 证书附加到端口 443:
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
而且我在 https://...443:/WCF/ 上没有其他保留 Url。
无论我尝试什么,我都会在 https:// DEV01:443/WCF/ 上收到 503 错误。 但是mex端点在https://DEV01:443/WCF/Mex上好像没问题。 我得到 Xml 结果。在 mex Xml 中,只有一件事对我来说似乎很奇怪:targetNamespace 在 mex 端点中等于 "http:// tempuri.org/"。
请帮我解决这个问题!
此致, 弗朗索瓦
我终于找到了让这个自托管服务正常工作的方法。 我不再在代码中使用参数。 我使用 app.config 定义了 99% 的 serviceHost 配置,并在代码中添加了一些参数(如证书管理)。
据我所知,这个例子有 0 次这样的机会! 很多人解释相反,但他们错了。
所以,有了app.config,我的代码就很简单了:
static void Main(string[] args)
{
ServiceHost serviceHost;
serviceHost = new ServiceHost(typeof(PCsService));
try
{
serviceHost.Open();
...
...
希望对其他人有所帮助!
此致。