Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB10

Hosted WCF Service over HTTPS

5.00/5 (3 votes)
28 May 2019CPOL3 min read 11.2K   257  
Example of a self hosted WCF service over HTTPS with transaction

Introduction

This article provides an example of a self hosted WCF service over HTTPS with transaction. The article describes how to create a self-signed certificate, how to bind it to a port, how to edit the config files, and how to run the service and the client. The WCF service and some configuration is from the blog post Self hosted WCF https works only when IIS has a site w https binding of Bill at Cape Cod.

Background

For a WCF Service to use SSL, a certificate must be binded to the port where the WCF Service runs. In production environments, a valid certificate must be installed. In development environments, a self-signed certificate may be created. Three ways are presented to create and bind a self-signed certificate:

  1. With IIS Manager
  2. With the command-line tools makecert and netsh http. However, makecert is deprecated
  3. With the provided CreateCert.bat which uses makecert, certutil and netsh http.

Certificate with IIS

Image 1

  1. Start IIS Manager for example through Start/Run/inetmgr.exe.
  2. Select the top node (computer name).
  3. Double-click on icon Server Certificates.
  4. Click on the link Create Self-Signed Certificate.

    Image 2

  5. Specify a friendly name for the certificate, for example IIS self-signed.

    Image 3

  6. The certificate is added to the list of certificates.

    Image 4

  7. Select the Default Web Site node and click on Bindings link.

    Image 5

  8. Set Port to 44400, choose SSL certificate IIS self-signed, and click on OK.

    Image 6

  9. You can check that the certificate is binded to port 44400 with the following command:
    netsh http show sslcert ipport=0.0.0.0:44400

    Image 7

Certificate with makecert and netsh http

  1. Check if certificate already registered for port 44400:
    netsh http show sslcert ipport=0.0.0.0:44400
  2. If certificate already exists, delete it with:
    netsh http delete sslcert ipport=0.0.0.0:44400
  3. Create certificate for localhost:
    "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\x64\makecert" -ss My -sr LocalMachine -n CN=localhost -r
    This will create the certificate localhost which you can see in Certificates Snap-in/Certificates (Local Computer)/Personal/Certificates.
  4. The Certificates Snap-in can be viewed with: Start/Run/mmc/File/Add/Remove Snap-in.../Certificates/Add/Computer account/Next/Local computer/Finish
  5. Make certificate trusted. In Certificates Snap-in copy-paste: from Personal/Certificates/localhost to Trusted People/Certificates
  6. Copy thumbprint of certificate to clipboard: Double click on Personal/Certificates/localhost, then select tab page Details, click on Field Thumbprint and select text in textbox and Ctrl-C.
  7. Add certificate to port:
    netsh http add sslcert ipport=0.0.0.0:44400 certhash=[certificate thumbprint] appid={12345678-1234-1234-1234-123456789012}
    appid seems not to play a role.
  8. You can check that the certificate is binded to port 44400 with the following command:
    netsh http show sslcert ipport=0.0.0.0:44400

    Image 8

Certificate with CreateCert.bat

The provided CreateCert.bat creates a self-signed certificate in store Personal and file c:\localhost.cer, imports c:\localhost.cer into store Trusted People, finds the thumbprint with certutil and registers that certificate with port 44400.

  1. Run as administrator CreateCert.bat. The output will be similar to the following:
    C:\Windows\system32>"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\makecert" -r -sk COMPUTER1 -sr LocalMachine -ss My -n CN=COMPUTER1,CN=localhost,CN=COMPUTER1 c:\localhost.cer
    Succeeded
    
    C:\Windows\system32>certutil -addstore TrustedPeople c:\localhost.cer
    TrustedPeople "Trusted People"
    Signature matches Public Key
    Certificate "COMPUTER1" added to store.
    CertUtil: -addstore command completed successfully.
    
    C:\Windows\system32>del c:\localhost.cer
    Created certificate with thumbprint=fa5ee6c56c066a5349ba64245e09580996ec5d56
    
    C:\Windows\system32>netsh http delete sslcert ipport=0.0.0.0:44400
    
    SSL Certificate deletion failed, Error: 2
    The system cannot find the file specified.
    
    C:\Windows\system32>netsh http add sslcert ipport=0.0.0.0:44400 certhash=fa5ee6c56c066a5349ba64245e09580996ec5d56 appid={12345678-1234-1234-1234-123456789012}
    
    SSL Certificate successfully added
    
    
    C:\Windows\system32>pause
    Press any key to continue . . .
  2. Do not mind about the error
    SSL Certificate deletion failed, Error: 2
    This command deletes any certificate from port 44400, and fails, if no certificate is binded to that port.
  3. You may check that port 44400 is binded to a certificate with the following command:
    BAT
    netsh http show sslcert ipport=0.0.0.0:44400
    This should produce an output similar to the following:
    SSL Certificate bindings:
    -------------------------
    
        IP:port                      : 0.0.0.0:44400
        Certificate Hash             : 022d408a952cbdd44ad0668f85254001510f4ee8
        Application ID               : {12345678-1234-1234-1234-123456789012}
        Certificate Store Name       : (null)
        Verify Client Certificate Revocation : Enabled
        Verify Revocation Using Cached Client Certificate Only : Disabled
        Usage Check                  : Enabled
        Revocation Freshness Time    : 0
        URL Retrieval Timeout        : 0
        Ctl Identifier               : (null)
        Ctl Store Name               : (null)
        DS Mapper Usage              : Disabled
        Negotiate Client Certificate : Disabled
        Reject Connections           : Disabled

Using the Code

The solution contains two projects:

  1. WCFService: Console application hosting a WCF Service
  2. WCFClient: Console application calling the WCF Service

The service implements only one method:

VB.NET
<ServiceContract()>
Interface ITestService
    <OperationContract()>
    <TransactionFlow(TransactionFlowOption.Mandatory)>
    Function GetResult() As String
End Interface

<ServiceBehavior(TransactionIsolationLevel:=
                 System.Transactions.IsolationLevel.Serializable, 
                 TransactionTimeout:="00:00:30", 
                 ReleaseServiceInstanceOnTransactionComplete:=False, 
                 TransactionAutoCompleteOnSessionClose:=False, 
                 IncludeExceptionDetailInFaults:=True)>
Public Class TestService
    Implements ITestService

    <OperationBehavior(TransactionScopeRequired:=True, TransactionAutoComplete:=True)>
    Public Function GetResult() As String Implements ITestService.GetResult
        Return String.Format("Hello, busy World. {0}", DateTime.Now.ToShortTimeString())
    End Function
End Class

The client just calls the service once:

VB.NET
Sub Main()
    Try
        Using tx As New TransactionScope()
            Dim client = New ServiceReference1.TestServiceClient
            Dim result = client.GetResult
            client.Close()
            Console.WriteLine(result)
            tx.Complete()
        End Using
    Catch ex As Exception
        Console.WriteLine(ex.ToString)
    End Try
    Console.ReadKey()
End Sub

The address of the WCFService is https://computer1.domain1.com:44400 and is registered in the app.config files of WCFClient and WCFService. You have to change this address to the one shown in the Certificates Snap-in:

Image 9

Now, everything should be configured. To test:

  1. Build solution.
  2. Start WCFService\bin\Debug\WCFService.exe. You probably have to run it as administrator.

    Image 10

  3. Start WCFClient\bin\Debug\WCFClient.exe. You probably have to run it as administrator. If everything went OK, the following will be displayed:

    Image 11

History

  1. WCF Service with transaction and SSL
  2. Added CreateCert.bat, which creates and registers the certificate with makecert, certutil, and netsh http sslcert.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)