我的服务使用以下代码在http上工作正常:
WebServiceHost serviceHost = new WebServiceHost(typeof(RestInterface), new Uri(http://localhost/rest));
serviceHost.Open();
当我尝试通过https托管完全相同的服务时,它无法正常工作。我在Service Trace Viewer中没有得到任何结果,Chrome只是说"这个网页不可用"。这是我用于https的代码:
var serviceHost = new WebServiceHost(typeof(RestInterface), new Uri(https://localhost/rest));
serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.Custom;
serviceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator =
new CertValidator(); // Custom validator that will accept any cert
serviceHost.Credentials.ServiceCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindBySubjectName,
"localhost");
var binding = new WebHttpBinding();
binding.Security.Mode = WebHttpSecurityMode.Transport;
var ep = serviceHost.AddServiceEndpoint(typeof(IRestInterface), binding, "");
ep.EndpointBehaviors.Add(new WebHttpBehavior());
serviceHost.Open();
有没有人得到这个工作?我做错了什么?!?
答案 0 :(得分:3)
好的,我终于明白了。我需要将证书绑定到端口。不要这样做:
serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.Custom;
serviceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator =
new CertValidator(); // Custom validator that will accept any cert
serviceHost.Credentials.ServiceCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindBySubjectName,
"localhost");
代替:
Process bindPortToCertificate = new Process();
bindPortToCertificate.StartInfo.FileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "netsh.exe");
bindPortToCertificate.StartInfo.Arguments = string.Format("http add sslcert ipport=0.0.0.0:{0} certhash={1} appid={{{2}}}", epAddress.Port, cert.Thumbprint, Guid.NewGuid());
bindPortToCertificate.Start();
bindPortToCertificate.WaitForExit();
这是我的工作代码。它仍然需要清理一下:
WebHttpBinding binding = new WebHttpBinding();
binding.Security.Mode = WebHttpSecurityMode.Transport;
serviceHost = new ServiceHost(typeof(RestInterface));
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
var cert = store.Certificates.Find(X509FindType.FindBySubjectName, "localhost", false)[0];
store.Close();
Process bindPortToCertificate = new Process();
bindPortToCertificate.StartInfo.FileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "netsh.exe");
bindPortToCertificate.StartInfo.Arguments = string.Format("http add sslcert ipport=0.0.0.0:{0} certhash={1} appid={{{2}}}", epAddress.Port, cert.Thumbprint, Guid.NewGuid());
bindPortToCertificate.Start();
bindPortToCertificate.WaitForExit();
var ep = serviceHost.AddServiceEndpoint(typeof(IRestInterface), binding, epAddress);
ep.EndpointBehaviors.Add(new WebHttpBehavior());
serviceHost.Open();