0


i want to secure a Silverlight App with SSL. So I try to wrote a proof of concept, where I host two BasicHttpBindings. One with BasicHttpSecurityMode.None and the other with BasicHttpSecurityMode.Transport.

But I not able to get the second one running, The WCFTestClient from VS Tools display this error message

// Error: Cannot obtain Metadata from https://localhost:8081/ If this is
// a Windows (R) Communication Foundation service to which you have
// access, please check that you have enabled metadata publishing at the
// specified address.  For help enabling metadata publishing, please
// refer to the MSDN documentation at
// http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange
// Error    URI: https://localhost:8081/    Metadata contains a reference
// that cannot be resolved: 'https://localhost:8081/'.    An error
// occurred while making the HTTP request to https://localhost:8081/.
// This could be due to the fact that the server certificate is not
// configured properly with HTTP.SYS in the HTTPS case. This could also
// be caused by a mismatch of the security binding between the client and
// the server.    The underlying connection was closed: An unexpected
// error occurred on a send.    Unable to read data from the transport
// connection: An existing connection was forcibly closed by the remote
// host.    An existing connection was forcibly closed by the remote
// hostHTTP GET Error    URI: https://localhost:8081/    There was an
// error downloading 'https://localhost:8081/'.    The underlying
// connection was closed: An unexpected error occurred on a send.   
// Unable to read data from the transport connection: An existing
// connection was forcibly closed by the remote host.    An existing
// connection was forcibly closed by the remote host

I would be great if some could view over my code, I stuck for two days with this. It need to be done all programmatically. Thanks a lot.

Almost the whole programm: http://pastebin.com/9j9K43tS

The Endpoints

private static readonly Uri UriBase = new Uri("http://localhost:8080/");
private static readonly Uri UriBaseService = new Uri("http://localhost:8080/Basic");

private static readonly Uri UriSecure = new Uri("https://localhost:8081/");
private static readonly Uri UriSecureService = new Uri("https://localhost:8081/Secure");

This Works

private static void BasicHTTPServer()
{
    var binding = new BasicHttpBinding();
    binding.Name = "binding1";
    binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
    binding.Security.Mode = BasicHttpSecurityMode.None;

    // Create a ServiceHost for the CalculatorService type and provide the base address.
    _serviceHost = new ServiceHost(typeof (ServiceBasic), UriBase);

    _serviceHost.AddServiceEndpoint(typeof (IServiceBasic), binding, UriBaseService);
    _serviceHost.AddServiceEndpoint(typeof (IPolicyRetriever), new WebHttpBinding(), "")
                .Behaviors.Add(new WebHttpBehavior());
    var smb = new ServiceMetadataBehavior {HttpGetEnabled = true, HttpGetUrl = UriBase};
    _serviceHost.Description.Behaviors.Add(smb);

    // Open the ServiceHostBase to create listeners and start listening for messages.
    _serviceHost.Open();
    Logger.Log(Server.Basic, string.Format("Open at {0} Service: {1}", UriBase, UriBaseService));
}

This doesn't Works

private static void SecureHTTPServer()
{
    var binding = new BasicHttpBinding();
    // it doesnt matter if I use BasicHttpsBinding or BasicHttpBinding
    binding.Name = "binding2";
    binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
    binding.Security.Mode = BasicHttpSecurityMode.Transport;
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

    // Create a ServiceHost for the CalculatorService type and provide the base address.
    _serviceHostSecure = new ServiceHost(typeof (ServiceBasic), UriSecure);
    _serviceHostSecure.Credentials.ServiceCertificate.Certificate = GetCertificate();
        //load a certificate from file
    _serviceHostSecure.Credentials.ClientCertificate.Authentication.CertificateValidationMode =
        X509CertificateValidationMode.None;

    _serviceHostSecure.AddServiceEndpoint(typeof (IServiceBasic), binding, UriSecureService);
    var webHttpBinding = new WebHttpBinding(WebHttpSecurityMode.Transport);
    webHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

    _serviceHostSecure.AddServiceEndpoint(typeof (IPolicyRetriever), webHttpBinding, "")
                      .Behaviors.Add(new WebHttpBehavior());
    var smb = new ServiceMetadataBehavior {HttpsGetEnabled = true, HttpsGetUrl = UriSecure};
    _serviceHostSecure.Description.Behaviors.Add(smb);

    // Open the ServiceHostBase to create listeners and start listening for messages.
    _serviceHostSecure.Open();
    Logger.Log(Server.Basic, string.Format("Open at {0} Service: {1}", UriSecure, UriSecureService));
}
hdev
  • 6,097
  • 1
  • 45
  • 62
  • I will take a wild guess and say something is wrong with your certificate. Can you call your Service's wsdl with a browser? It should tell you exactly what is wrong with your certificate, depending on browser type you may need to "view technical details" from the warning message or click on the red icon next to the crossed out https symbol. Silverlight is extremly picky when it comes to HTTPS, it won't accept anything less than perfect certificates. – nvoigt Feb 24 '13 at 10:12
  • I can visit http://localhost:8080/ but not https://localhost:8081/ with my browser. Message: "Interrupt during load" – hdev Feb 24 '13 at 10:21
  • This [SO: https from console app?](http://stackoverflow.com/questions/10274207/https-from-console-app/10373991#10373991) is what you need to do to get HTTPS working – Petar Vučetin Feb 24 '13 at 15:35
  • @Petar I want to use BasicHttpBinding. – hdev Feb 25 '13 at 08:09

0 Answers0