Wednesday, July 30, 2014

Protect a WCF service using SSL - Part 2

In a prior post, I described how to protect a WCF service using SSL.  In the service .config file, you must do the following in order to expose the https endpoint:

<configuration>
  <system.serviceModel>
    <protocolMapping>
      <add scheme="https" binding="basicHttpsBinding" />
    </protocolMapping>
  </system.serviceModel>
</configuration>

The client configuration also needs some specific settings:

    <system.serviceModel>
        <bindings>
          <basicHttpsBinding>
            <binding name="BasicHttpsBinding_IDayOfTheWeekService"></binding>
          </basicHttpsBinding>
        </bindings>
        <client>
            <endpoint address="https://computername.yourdomain.net/WcfSecureServer/DayOfTheWeekService.svc"
                binding="basicHttpsBinding" bindingConfiguration="BasicHttpsBinding_IDayOfTheWeekService"
                contract="DayOfTheWeekReference.IDayOfTheWeekService" name="BasicHttpsBinding_IDayOfTheWeekService" />
        </client>
    </system.serviceModel>

Note that I am using basicHttpsBinding.  This just came out with .NET 4.5.  It's exactly the same as basicHttpBinding except the <security mode="Transport" /> is default so you don't have to specify this.  Also, if you generate your own certificate, you will get an error message that says something like:
Could not establish trust relationship for the SSL/TLS secure channel with authority 'localhost'
This is because WCF doesn't trust your self generated cert.  However, if you generate a certificate with the name of the computer that it is issued to, and specify the fully qualified name of the computer in the URL like I did above, WCF will allow it.

Tuesday, July 29, 2014

Specify ASP.NET timeout

ASP.NET will only allow a request to execute for 110 seconds by default.  This can be easily extended in the web.config with the following attribute:

<configuration>
  <system.web>
    <httpRuntime executionTimeout="300" />
  </system.web>
</configuration>

This example sets the timeout to 300 seconds.

Friday, July 18, 2014

WCF and ASP.NET Web API

When writing web services using .NET technology, you have a few options.

WCF:  Tried and true, this is the successor to the original ASMX style web services.  WCF has capabilities to create any type of service that can be accessed over a network, not just HTTP.  WCF tends to be a bit configuration heavy requiring the use of a special tool in Visual Studio to set the myriad of options up.  WCF generally uses the SOAP protocol.  While it is possible to create a REST style web service using WCF, it is recommended by Microsoft to use Web API technology for REST style web services.

ASP.NET Web API:  Web API allows you to create a REST style web service (no SOAP support) using an architecture that is very similar to MVC.  You create a set of controllers and configure a routing system to create your operations and accept parameters.  This tends to be simpler to setup and configure as it is very close to what you would do to configure an MVC web application.

There are also a couple of terms that need to be defined:

REST style web service:  When you apply a REST architecture to a web service, this changes the way in which the client calls the operations of the web service.  With a traditional web service, each call is represented by an HTTP GET verb with the URL that represents the name of the operation.  With a REST style web service, the URL represents a set of operations that are differentiated by the use of 4 different HTTP verbs (GET, POST, PUT, and DELETE).   I believe that the advantage of REST is that it is (allegedly) easier and makes more sense when called from client side code like JavaScript.  Therefore, it can be consumed by a wider variety of devices.  Also REST is necessary when implementing a data API using the OData protocol.

OData Protocol:  OData is set of specifications for creating a data API.  A data API is a service that exposes your database more directly over the web.  Instead of abstract operations that perform CRUD operations on the callers behalf, the data API allows the consumer to perform the CRUD operations nearly directly.  For example, each table could be represented as a URL and the user could query the table directly or even join together multiple tables.  This has the effect of moving the business logic to the client.

Conclusions

Using OData to access a database over the internet sounds like it could be useful.  And obviously you need to use REST in order to implement this.  However, setting up an OData endpoint using Web API is anything but straight forward right now.  In my opinion, this technology needs to mature a little longer for me to recommend using it.

If you're not going to use OData, then I just don't see the big advantage of using REST.  It seems to me that it would be awkward to organize your operations into sets of four HTTP verbs.  Another big disadvantage to using REST, is that there is no automatic proxy generation for consumers of REST style services.  Web API does seem like it works well, but it requires a REST style architecture.

This is my bottom line:  If you want to use a REST architecture, use Web API.  If you want to use a SOAP architecture, then use WCF.  At this time, I will continue to use SOAP and therefore WCF.

Wednesday, July 16, 2014

WCF Message Tracing

Message Tracing logs details on each communication in and out of the web service.  When making significant configuration changes, it is almost always best to use the Microsoft Service Configuration Editor to edit the web.config.  In many cases, it is just not practical to edit the web.config directly.  To access the editor, in the Visual Studio Solution Explorer, right click the web.config of the service and click Edit WCF Configuration.

To configure message tracing, follow these steps in the Configuration Editor:

  1. In the Diagnostics folder, click Message Logging and set LogEntireMessage to True.  Also set LogMessagesAtServiceLevel and/or LogMessagesAtTransportLevel to True, depending on your needs.  Most of the time these messages will be identical.  If you are encrypting at the message level, then the message logged at the transport level will be encrypted.  If you are encrypting at the transport level, then both will be unencrypted and practically identical.  The Transport Level is the host level.  So this is logged when the host (IIS in most cases) redirects the message to the service.  The Message Level is the actual service level.
  2. In the Diagnostics folder, right-click Sources and choose New Source.
    • From the drop down, choose System.ServiceModel.MessageLogging
    • Choose Verbose as the Trace Level.
  3. In the Diagnostics folder, right-click Listeners and choose New Listener.
    • Type "MessageLog" as the Name.
    • In the InitData field, use the browse button to set a path and filename of the logfile.
    • TraceOutputOptions:  Click the drop down and select which options you want.  I just like to include the DateTime
    • TypeName:  Click the ellipses and choose System.Diagnostics.XmlWriterTraceListener
To view the log file, you want to use a tool called Microsoft Service Trace Viewer.  I believe this is included with Visual Studio.  To find it just do a search using the start button for Service Trace Viewer.  Or try just right-clicking the log file and choosing Open.

An alternative way to accomplish this is:

  1. Click the Diagnostics folder and then click the Enable Message Logging link.
  2. Set the Log Level by clicking the link next to the "Log Level:" label and only check the Service messages box.
  3. Click on the link of the listener, and choose a location and options as described above.
  4. You may also want to click the Message Logging node and choose Log Entire Message.
  5. You may also want to click the Source that was created and select Verbose.



UPDATE 7/22/2015:  Curiously, I couldn't find it on a PC that I know has .NET installed.  I found it here:  C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools

UPDATE 7/24/2015:  Added the alternative method of setting up tracing.  I had some issues getting the standard method to work.

Tuesday, July 15, 2014

Protect a WCF service using SSL - Part 1

We have a scenario where we are exposing a WCF service over the internet that is hosted in IIS.  We want the communication with the service to be protected using SSL.  The encryption/decryption is handled completely by IIS, so there is minimal need to edit the configuration of the service itself (See Part 2).  First you need a certificate.  To create your own for testing:

  1. Open IIS (as administrator).
  2. Choose the top level node in the Connections pane.
  3. Click Server Certificates in the IIS section of the middle pane.
  4. Click Create Self Signed Certificate.  The friendly name should match the name of the computer.
Now configure SSL:
  1. Right click Default Web Site and choose Edit Bindings.
  2. Click Add, choose HTTPS, and select the certificate you just created.
Finally, set up your service to require SSL:
  1. Click on the web application that hosts your service.
  2. In the middle pane, IIS section, double click on SSL Settings and check the "Require SSL" box.