locked
client configuration for WCF RESTful service using Windows Authentication and SSL RRS feed

  • Question

  • Hello All,

    I implemented a simple WCF service using the webHttpBinding and configured my endpoint to use Windows Authentication and SLL; as follows:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.serviceModel>
        <services>
          <service name="AssetService.Service.AssetService">
            <endpoint address=""
                      binding="webHttpBinding"
                      contract="AssetService.Contracts.IAsset"
                      behaviorConfiguration="web"
                      bindingConfiguration="webBinding" />
          </service>
        </services>
        <bindings>
          <webHttpBinding>
            <binding name="webBinding">
              <security mode="Transport">
                <transport clientCredentialType="Windows"/>
              </security>
            </binding>
          </webHttpBinding>
        </bindings>
        <behaviors>
          <endpointBehaviors>
            <behavior name ="web">
              <webHttp/>
            </behavior>
          </endpointBehaviors>
        </behaviors>
      </system.serviceModel>
    </configuration>
    


    The service is hosted in IIS 6, which is configureg to use Windows auth and secure communication. I created a self signed certificate and installed on the server (this cert is used for SSL).

    I then implement my client like:

       var http = new HttpClient()
                    {
                       TransportSettings = new HttpWebRequestTransportSettings
                       {
                           Credentials = CredentialCache.DefaultNetworkCredentials,
                       },
                       BaseAddress = new Uri("https://myHost/AssetService/Service.svc/"),
                    };
                    HttpResponseMessage resp = http.Get();
                    resp.EnsureStatusIsSuccessful();
    

    This code succeeds if I run it in locally on my app server. If I run this code from another machine, I get a 500 error (Internal error). If I open the URL corresponding to this request in IE, I get a "certificate error screen" (like the one below). By selecting continue, I get a valid result.




    As an experiment, I changed the web.config of my service to use  TransportCredentialOnly and configured IIS NOT to use SSL. In this case,my client succeeds when running from a remote client. Unfortunately, it is a requirement to use Windows auth with SSL, since the http request contains sensitive information.  Am I missing something in my client or service configuration? Am I using the certificates correctly?

    Any help is greatly appreciated.


    Kind regards
    CD





    Monday, October 12, 2009 6:20 AM

Answers


  • for your development env, you can handle the ServerCertificateValidationCallback and do nothing for now.  Look at the sample below.
     

    using System;
    using System.Net;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    using Microsoft.Http;
    
    namespace HttpClientHttps
    {
        class Program
        {
            static void Main(string[] args)
            {
                HttpClient client = new HttpClient(new Uri(@"https://XXXXXXX/test/service1.svc"));
                ServicePointManager.ServerCertificateValidationCallback  = 
                (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)=>
                {
                    return true;
                };
                
               
                string s = client.Get().Content.ReadAsString();
            }
        }
    }

    Amit Sharma
    Tuesday, October 13, 2009 6:48 PM

All replies

  • I think this is how the self signed certs will work.
    If you view the certificate and look at the 'Issused to' value, you will see a domain name listed there.
    From your remote machine, if you now use that exact domain name to browse to your service then you will see that the second certificate error mesasage will go away. 

    The first error 'The security certificate presented by this website was not issued by a trusted certificate authority' will still be there.  This is because exactly what the message says, you are not authorized to issue certificates.  Self signed certificates should only be used in the development phase.  You will have to buy a cert from an authorized vendor, such as Verisign, before you go to production.
    Amit Sharma
    Monday, October 12, 2009 4:15 PM
  • Hello Amit,

    Thank you for your reply. Although I understand the behavior of self signed certs in IE (and we plan to deploy using a valig cert), I still have a problem. During development I use self signed certs but I am unsuccessful in calling my service from my client using the configuration of the HttpClient shown in my first post:

    var http = new HttpClient()
                    {
                       TransportSettings = new HttpWebRequestTransportSettings
                       {
                           Credentials = CredentialCache.DefaultNetworkCredentials,
                       },
                       BaseAddress = new Uri("https://myHost/AssetService/Service.svc/"),
                    };
     HttpResponseMessage resp = http.Get();
    resp.EnsureStatusIsSuccessful();
    


    As I call the http.Get(), I get a HttpSageProcessingException thrown by the Microsoft.Http dll. The Inner exception message is "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel." The inner-inner exception message is "The remote certificate is invalid according to the validation procedure.". 

    So the question is: How can I code my client in my development environment to successfully access the service despite the certificate error? (Just like IE does as I select the 'Continue to this Web site" button in the certificate error page)

    Any help is greatly appreciated.

    Kind regards
    CD





    Tuesday, October 13, 2009 5:56 PM

  • for your development env, you can handle the ServerCertificateValidationCallback and do nothing for now.  Look at the sample below.
     

    using System;
    using System.Net;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    using Microsoft.Http;
    
    namespace HttpClientHttps
    {
        class Program
        {
            static void Main(string[] args)
            {
                HttpClient client = new HttpClient(new Uri(@"https://XXXXXXX/test/service1.svc"));
                ServicePointManager.ServerCertificateValidationCallback  = 
                (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)=>
                {
                    return true;
                };
                
               
                string s = client.Get().Content.ReadAsString();
            }
        }
    }

    Amit Sharma
    Tuesday, October 13, 2009 6:48 PM