Saturday, September 7, 2019

How to Configure wsHttpBinding to use transport security?

We will discuss configuring wsHttpBinding to use transport security mode and basic client credential type.

The following are the defaults of wsHttpBinding 
Security Mode - Message
ClientCredentialType - Windows

The following MSDN article contains all the system provided bindings and their security defaults.
http://msdn.microsoft.com/en-us/library/ms731092(v=vs.110).aspx

Here are the steps to configure wsHttpBinding to use transport security mode and basic client credential type. 
Step 1: Create a class library project with name = SimpleService. Delete the auto-generated class1.cs file.

Step 2: Right click on SimpleService project in solution explorer and add a WCF service with name = SimpleService

Step 3: Copy and paste the following code in ISimpleService.cs file
using System.ServiceModel;
namespace SimpleService
{
    [ServiceContract]
    public interface ISimpleService
    {
        [OperationContract]
        string GetMessage(string name);
    }
}

Step 4: Copy and paste the following code in SimpleService.cs file
using System;
using System.ServiceModel;

namespace SimpleService
{
    public class SimpleService : ISimpleService
    {
        public string GetMessage(string name)
        {
            return "Hello " + name;
        }
    }
}

Step 5: Now, let's host the WCF service in IIS. We discussed this in detail in Part 29 of WCF tutorial. Right click on SimpleService solution in Solution Explorer and select Add - New Web Site. Fill in the details as shown in the image below.
Hosting wcf service in iis

Step 6: Delete IService.cs and Service.cs files that are present under App_Code folder.

Step 7: Add a reference to SimpleService WCF library. To do this, right click on SimpleService\SimpleServiceIISHost project in Solution Explorer and select "Add Reference" option and add a reference to SimpleService project.

Step 8: Rename Service.svc file to SimpleService.svc. Copy and paste the following code in SimpleService.svc file.
<%@ ServiceHost Language="C#" Debug="true" Service="SimpleService.SimpleService"%>

Step 9: Copy and paste the following code in web.config file
<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mexBehavior">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="mexBehavior"
               name="SimpleService.SimpleService">
        <endpoint address="SimpleService" binding="wsHttpBinding"
            contract="SimpleService.ISimpleService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Step 10: Configure IIS
a) Open IIS. In the run window, type INETMGR and press enter key.
b) Expand Sites folder. Right click on "Default Web Site" and select "Add Application" option.
c) In "Add Application" make sure you have the following settings and click OK.
    Alias = SimpleService
    Application pool = ASP.NET v4.0
    Physical path = C:\SimpleService\SimpleServiceIISHost

Step 11: Enable message logging for the WCF Service. We discussed this in detail in Part 9 of WCF tutorial.

Step 12: Now let's create a client for the WCF service. Create a new windows forms application with name = Client

Step 13: Add a service reference to SimpleService. Right click on References folder and select Add Service Reference. In the Add Service Reference window type Address = http://localhost/SimpleService/SimpleService.svc and click GO button. This should bring up the SimpleService. In the Namespace textbox type SimpleService and click OK. At this point, notice the configuration in the app.config file of the client application. Notice that the defaults of wsHttpBinding are being used
<security mode="Message">
<message clientCredentialType="Windows"/>

Step 14: Drag and drop a button control on Form1. Set the following properties on button1
Name = btnCallService
Text  = Call Service

Step 15: Double click on the button to generate the "click event handler" method. Copy and paste the following code in Form1.cs file.
using System;
using System.Windows.Forms;

namespace Client
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnCallService_Click(object senderEventArgs e)
        {
            SimpleService.SimpleServiceClient client =
                new SimpleService.SimpleServiceClient();
            MessageBox.Show(client.GetMessage("Pragim"));
        }
    }
}

Step 16: Run the WCF service and the client applications. Click the button to invoke the service. Inspect the logged messages and notice that the body of the SOAP message is encrypted, which implies that the wsHttpBinding is using message based security.

Step 17: Create a self-signed SSL certificate using IIS. We discussed creating self signed certificates in Part 101 of ASP.NET tutorial.

Step 18: In IIS, add Https binding using the self-signed SSL certificate created in Step17.
creating https binding in iis

Step 19: In IIS, configure SSL settings for SimpleService
a) To do this, select "SimpleService" and double click on "SSL Settings"
configure SSL settings in iis

b) Select "Require SSL" check box and "Accept" radio button under "Client certificates" and then click on "Apply" link button.
configuring SSL settings in iis

Step 20: In web.config, include the following bindings section, to customize the wsHttpBinding to use Transport security and Basic client credential type.
<bindings>
  <wsHttpBinding>
    <binding name="wsHttp">
      <security mode="Transport">
        <transport clientCredentialType="Basic"></transport>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

Step 21: Associate the above customization with the service endpoint using bindingConfiguration attribute as shown below.
<endpoint address="SimpleService"
          binding="wsHttpBinding"
          contract="SimpleService.ISimpleService"
          bindingConfiguration="wsHttp"/>

Step 22: At this point, trying to navigate to https://localhost/SimpleService/SimpleService.svc will throw the following error.
Security settings for this service require 'Basic' Authentication but it is not enabled for the IIS application that hosts this service.

Step 23: To fix the above error, enable 'Basic' Authentication in IIS. To do this
a) In IIS, select "Simple Service" under "Default Web Site" and then double click on "Authentication" icon.
enable Basic Authentication in IIS

b) Select "Basic Authentication" and then click on "Enable" link
enabling Basic Authentication in IIS

Step 24: Trying to navigate to https://localhost/SimpleService/SimpleService.svc will throw the following error.
The HttpGetEnabled property of ServiceMetadataBehavior is set to true and the HttpGetUrl property is a relative address, but there is no http base address.  Either supply an http base address or set HttpGetUrl to an absolute address.

Step 25: To fix the above error, change <serviceMetadata httpGetEnabled="true" /> to <serviceMetadata httpsGetEnabled="true" />. Save the changes and then navigate to https://localhost/SimpleService/SimpleService.svc. At this point we should be able to see the SimpleService WSDL.

Step 26: In the client application, delete the SimpleService service reference, and then add the service reference again to SimpleService. This time use https://localhost/SimpleService/SimpleService.svc instead of http://localhost/SimpleService/SimpleService.svc. Notice that we are using Https instead of Http.  At this point, notice the configuration in the app.config file of the client application. Notice that instead of the defaults of wsHttpBinding, we are now using "Transport" security mode and "Basic" client credential type.
<security mode="Transport">
<transport clientCredentialType="Basic"/>

Step 27: Run the client application, and then click "Call Service" button. The following error will be thrown.
The username is not provided. Specify username in ClientCredentials.

Step 28: To fix the above error, modify the code in btnCallService_Click() event handler method in Form1.cs of the client application as shown below.
private void btnCallService_Click(object senderEventArgs e)
{
    SimpleService.SimpleServiceClient client = new
        SimpleService.SimpleServiceClient();
    client.ClientCredentials.UserName.UserName = "WindowsUserName";
    client.ClientCredentials.UserName.Password = "Password";
    MessageBox.Show(client.GetMessage("Pragim"));
}

Step 29: Run the client application, and then click "Call Service" button. We now get the out put as expected.  Inspect the logged messages and notice that the body of the SOAP message is not encrypted, which implies that the wsHttpBinding is now using Transport security.












No comments:

Post a Comment

Get max value for identity column without a table scan

  You can use   IDENT_CURRENT   to look up the last identity value to be inserted, e.g. IDENT_CURRENT( 'MyTable' ) However, be caut...