如何在不使用app.config的情况下通过https自托管WCF REST XML服务?

时间:2014-05-09 14:24:29

标签: .net web-services wcf rest c#-4.0

我的服务使用以下代码在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();

有没有人得到这个工作?我做错了什么?!?

1 个答案:

答案 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();

取自: http://blogs.msdn.com/b/james_osbornes_blog/archive/2010/12/10/selfhosting-a-wcf-service-over-https.aspx

这是我的工作代码。它仍然需要清理一下:

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();