Skip to main content

WCF self hosted service over HTTPS

In this post I will show you how to host self hosting wcf service over ssl.

Let's create a simple wcf service


Create a new console application in visual studio and paste the following code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace SelfHostSSL
{
    [ServiceContract]
    public interface IGreeting
    {
        [OperationContract]
    string SendGreeting();
    }
    public class Implementation : IGreeting
    {
        
    public string SendGreeting()
        {
    return "Hello world";
        }
        
    }
    class Program
    {
    static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(Implementation));
            host.Open();
            Console.WriteLine("Service is ready");
            Console.ReadLine();
        }
    }
}

After that add new item app.config and paste following code in it

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
    <system.serviceModel>
    <behaviors>
    <serviceBehaviors>
    <behavior name="serviceBehav">
    <serviceDebug />
    <serviceMetadata httpGetEnabled="true" httpGetUrl="mex" />
    </behavior>
    </serviceBehaviors>
    </behaviors>
    <services>
    <service behaviorConfiguration="serviceBehav" name="SelfHostSSL.Implementation">
    <endpoint address="basic" binding="basicHttpBinding"
    bindingConfiguration="" contract="SelfHostSSL.IGreeting" ></endpoint>
    <host>
    <baseAddresses>
    <add baseAddress="http://localhost:4490/"/>
    </baseAddresses>
    </host>
    </service>
          
    </services>
      
    </system.serviceModel>
</configuration>


Add new project named Client in same solution and paste following code in it


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace Client
{
    [ServiceContract]
    public interface IGreeting
    {
        [OperationContract]
    string SendGreeting();
    }
    
    class Program
    {
    static void Main(string[] args)
        {
            ChannelFactory<IGreeting> proxy = new ChannelFactory<IGreeting>(new BasicHttpBinding());
            proxy.Endpoint.Address = new EndpointAddress("http://localhost:4490/basic");
    string result = proxy.CreateChannel().SendGreeting();
            Console.WriteLine(result);
        }
    }
}

Our simple wcf service is ready now.Let's configure it for ssl. Open app.config and make highlighted changes

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="serviceBehav" name="SelfHostSSL.Implementation">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="serviceBinding" contract="SelfHostSSL.IGreeting"></endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:8080/basic"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <bindings>
    <basicHttpBinding>
    <binding name="serviceBinding">
    <security mode="Transport">
    </security>
    </binding>
    </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="serviceBehav">
          <serviceDebug/>
          <serviceMetadata httpsGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

When you run the service after making above changes service will throw following exception.


AddressAccessDeniedException: HTTP could not register URL http://+:8080/<…>.  Your process does not have access rights to this namespace.



To fix this problem, the owner of the HTTP namespace (built-in administrator) needs to delegate this ownership to the user account under which you are running your application (most of the times, it's the logged on user). To do this, start a command prompt using "Run as administrator" so that you have elevated privileges. Then, use netsh.exe to give some of the Administrator's HTTP namespace to your user account. You can look at the existing HTTP namespace delegations by using "netsh http show urlacl".





Execute the above command and run the service.If every thing is fine then you will see "service ready " message.

Try to browse the service from browser you will see page can not found error message

This is because our port is not open for SSL.Now you have to create a self -signed certificate for this follow the following two links and create a self signed certificate and note down the thumbprint value a remove the extra space.

How to create Self-Signed SSL Certificate using OpenSSL

How to create self signed certificate using makecert 

Now,It's time to configure the port for SSL (check out this for more details)
Open the command prompt in elevated mode and run the following command


Command Description:

netsh http add sslcert [Ipaddress:port] certhas=[thumbprint of certifcate] appid={unique id for application.you can use GUID for this]

Comments

Popular posts from this blog