0

I've used this example project as a starting point, but modified it to use HTTPS and TransportWithMessageCredential.

I'm running the server through IIS Express with SSL Enabled and the project is functioning.

The thing I am a bit unsure about is the SSL certificate, as I have to set the client to accept all certificates for it to work.

Server config:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Behavior1">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
          <serviceCredentials>
            <serviceCertificate findValue="MyWebSite"
                  storeLocation="LocalMachine"
                  storeName="My"
                  x509FindType="FindBySubjectName" />
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Service.UserNamePassValidator, Service" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="Binding1">
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="Certificate" />
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="Behavior1" name="Service.Service">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1" contract="Service.IService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost/" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Client config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IService">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://localhost:44303/UsernamePasswordService.svc"
        binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService"
        contract="ServiceReference1.IService" name="WSHttpBinding_IService" />
    </client>
  </system.serviceModel>
</configuration>

Client code:

private void button1_Click(object sender, EventArgs e)
{
   string time = "";
   var c = new ServiceClient();
   c.ClientCredentials.UserName.UserName = txtUser.Text;
   c.ClientCredentials.UserName.Password = txtPassword.Text;
   c.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;

   ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate;

   try
   {
       time = c.GetServertime();
       MessageBox.Show(time, "You are authenticated");
   }
   catch (Exception ex)
   {
       if (ex.InnerException != null)
           MessageBox.Show(ex.InnerException.Message, "Incorrect username/password");
       else
           MessageBox.Show(ex.Message, "Unhandled exception");
   }
}

private static bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
{
    // trust any certificate
    return true;
}

As you can see from the client code all certificates are trusted in RemoteCertificateValidate(). I found that as an example for working around self-signed certificates when developing.

I dont quite understand why setting

CertificateValidationMode = X509CertificateValidationMode.None;

isnt giving the same effect. Shouldnt this set client to not validate the certificate?

As I am still quite new to understanding how SSL certificates are distributed, the thing I'm a bit unsure about is how this will work when we get a valid SSL certificate. Will the certificate have to be installed on all the clients?

I also tried logging the traffic from the client to the server, and noticed the following in one of the messages sent:

<o:Username>
<!-- Removed-->
</o:Username>
<o:Password>
<!-- Removed-->
</o:Password>

does this mean that the username and password is being sent in clear text?

Avilan
  • 608
  • 2
  • 6
  • 23
  • When you get an actual SSL certificate issued by a proper trusted authority you would not need to install the SSL on client machines. When a client accesses your service via https the certificate validation is done by navigating thru the chain to find the issuer and if that issuer certificate is in the trusted list, if it is then it passes the validation – Rajesh Dec 19 '13 at 15:47
  • Isnt it possible to set it up so that I wouldnt have to install the certificate on the client machines? I already use username and password to validate them. – Avilan Dec 19 '13 at 16:24
  • You never install a certificate on a client machine unless you want to perform your 2 way SSL authentication for both server and client identification. Since you are using Username/Password authentication the client code should handle the server certificate validation error(when using selfsigned cert) with the ServicePointManager.ServerCertificateValidationCallback and once you replace with proper cert (fully signed) the client would not need to do anything – Rajesh Dec 20 '13 at 09:45
  • Then what about the traffic sent from the client to the server? Will it be encrypted using the server's certificate or will it just be sent in plain text? Do I have to encrypt the data sent myself? – Avilan Dec 20 '13 at 11:10
  • When you access a URL via HTTPS the channel is encrypted with the server certificate and messages are transferred in it. You can still encrypt the messages and configure the server to decrypt the message as well – Rajesh Dec 20 '13 at 11:42

0 Answers0