How to use soapUI 5.0 to post JSON to REST Service

I wrote an article on the same topic but with version 4.5.1 soapUI back in 2013. To post JSON with an 4.5.1 version soapUI, you almost have to trick the application by explicitly typing in the media type ‘application/json’, and there are also a few settings that don’t really make sense. I’ve always forgotten the steps and had to go back to check my blog post.

Since then I have tried a couple of newer versions of soapUI for the same task, hoping it got more intuitive, but eventually I stuck with the 4.5.1 version because I didn’t see much improvement in those versions. Today I get my hands on the latest 5.0 version of the tool. Still free, great!
First, I crate a new SOAP project. The ‘Opens dialog to create REST Service’ option is gone. OK. It is already simpler from the first step.
1

Now my project is created, I right click the project and select New REST Service from URI.

2

In the popup window, I put in the service endpoint where I am going to post my JSON to.

3

BOOM! It creates everything for me. No need to provide a Service Name, Parameter Name, or Method Name, everything is extracted from the endpoint provided. This is a great UI design because if out of nowhere it asks the user to provide a Service Name, she will be confused – What is the Service Name for?

4

It also automatically opens up Request1 where you can see it by default selects GET method.

5

I changed the Method to POST. It selects the correct Media Type for JSON posting. Just type in your JSON body and click the green arrow on the left top corner to post.

6

I am impressed by how easy the process becomes and glad that the development team is putting efforts on improving user experience, even though it is already a well-functional application. User experience is really a big part of software. A good UX can really change your life!

Use Windows Authentication on WCF service behind a SSL handler

After my last blog post about using Cert-based Message security for WCF web service, we started to look into using Windows Authentication for a different system that also sits behind a load balancer/SSL handler. Windows Authentication provides a much easier integration option – client side can simply provide a domain user account to be authenticated, where as in Cert-based authentication, each client needs to install a certificate. This increases difficulties for clients to develop against the service and is our motivation to look into utilizing Windows Authentication instead.

With the experience of cert-based authentication, I was pretty sure it wasn’t going to be easy to use Windows Authentication in a load balanced environment. First thing we tried of course is to follow Microsoft’s guide to use wsHttpBinding with Windows Authentication and Message Security, with one different is that our client needs to use Transport security instead of Message because it must use HTTPS.

Like we thought, this setup didn’t work because the service expect to use Message security but the client is using Transport security. We then tried TransportWithMessage credential and some other settings. None of them works. We were stuck on this error message “The HTTP request is unauthorized with client authentication scheme ‘Ntlm’. The authentication header received from the server was ‘Negotiate,NTLM’.“, which unfortunately is one of those error messages that do not make sense.

In the painful process of pursuing truth, we came across some post raising the problem level to the load balancer level, which discouraged us to keep researching. It seemed more reasonable to find an alternative at that point, and we did find out that using BasicHttpBinding with Windows Authentication and TransportCredentialOnly worked in our environment.

Here is our client setup:

<basicHttpBinding>
  <binding name="BasicHttpBinding">
   <security mode="Transport">
    <transport clientCredentialType="Basic" />
   </security>
  </binding>
</basicHttpBinding>

Service setup:

<basicHttpBinding>
  <binding name="BasicHttpEndpointBinding">
    <security mode="TransportCredentialOnly">
      <transport clientCredentialType="Basic"/> 
    </security>
  </binding>
 </basicHttpBinding>

The problem with this is that the credentials of the client is passed in clear text. Although message before the land balancer is protected by HTTPs, still we want a true end-to-end protection on the credentials. So this solution is off the table. We decided to go back to our original plan.

I will just skip to the end of the story because I like magic!… We eventually found a solution that worked in the load balanced environment. Custom binding once again saved the world! I didn’t find any article about this configuration, which makes it more important to share it with everyone.

Client side:

 <customBinding>
  <binding name="customBinding_WindowsAuth">
    <textMessageEncoding>
      <readerQuotas />
    </textMessageEncoding>
    <security authenticationMode="SspiNegotiated"></security>
    <httpsTransport  authenticationScheme="Anonymous"  
      proxyAuthenticationScheme="Anonymous" useDefaultWebProxy="true">
    </httpsTransport>      
  </binding>
</customBinding>

Service side:

<wsHttpBinding>
 <binding name="WsBindingConfigration" >      
   <security mode="Message">
     <message clientCredentialType="Windows" 
     negotiateServiceCredential="true" algorithmSuite="Default" 
     establishSecurityContext="false"/>
   </security>
 </binding>
</wsHttpBinding>

Use Message security on WCF service behind a SSL handler

Configuring WCF web service’s security is just tedious. Microsoft has been trying to make it simple by removing many configuration settings in .NET 4.5 but it could still get messy if you need to touch the security part – There are many bindings and there are Message, Transport, and TransportWithMessageCredentials security modes, each with their own client credential types, not mentions all those authentication modes for Custom Bindings such as AnoymousForCertificate, IssuedTokenForCertificate, IssuedTokenOVerTransport, etc.

Developers are developing WCF web service on the platform from Microsoft. They are the users of the platform in this sense. It’s supposed to be user friendly and intuitive. But I found it is quite difficult to select the right security configuration in different scenarios. Even after you read the documentation from Microsoft carefully, you sill have a very limited idea on how these security modes differentiate from each other.

This post is aimed to cover one small scenario of using WCF security – using a WCF web service with cert-based Message security behind a front-end SSL handler. Often times, your web servers are behind a load balancer that handles all SSL requests and pass in HTTP requests to your IIS. Below is diagram showing the infrastructure.

8-8-2014 4-17-55 PM

At first glance, it seems pretty straightforward – Transport security mode covers SSL security, Message security mode handles message encryption. Hey there is a security mode just for the two modes combined: TransportWithMessageCredentials . We should be able to just use that on both client and service side to achieve what we want, right? However, you just can’t be so optimistic in the world of software development.

This configuration won’t working. First of all, since the service is not really receiving HTTPS requests, Transport mode should not be used. We just need Message security. So below is the correct configuration on service side.

<wsHttpBinding>
     <binding name="WsBindingConfigration">
     <security mode="Message">
      <message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="false"/>
     </security>
    </binding>
  </wsHttpBinding>

The client side is where it gets tricky. I can’t really explain why TransportWihtMessageCredential doesn’t work. Something goes wrong under the hood. But here is the configuration worked for me. Use MutualSSLNegotiated mode and CustomBinding!

<customBinding>
        <binding name="customBinding_CertAuth_ClientService">
           <security authenticationMode="MutualSslNegotiated">
           </security>
           <httpsTransport authenticationScheme="Anonymous"
proxyAuthenticationScheme="Anonymous" useDefaultWebProxy="true">
           </httpsTransport>
        </binding>
</customBinding>

It took me a long while to research and trial and error to finally figure this out. Many development teams don’t have the time to mirror the environments of their clients, which makes finding and troubleshooting issues like this difficult. But hopefully this post can help you out.

 

Easiest way to test SQL Server connection

The other day I found an interesting way to test SQL Server database connection. It is very easy and quicker than what I usually do. For those of you who like moving pictures, here is a video tutorial.

To test database connection, what I usually do is to make sure port is open by using Telnet command and then use a tool like SQL Command Line, or SQL Server Management Studio,  Visual Studio Server Explorer, etc. If none of these tools is available, we can still use ODBC Data Source tool to test.  However, there is another way, a shortcut approach.

Create a new .txt file, change the file extension from .txt to .UDL, and then open the Properties of the file. In the Connection tab, you can test database from there!

7-1-2014 10-39-33 AM

Also in the Provider tab, you can select any provider for the test.

7-1-2014 11-08-30 AM

If you save the database connection in the Properties window, you can find the connection string by opening the UDL file with Notepad.

One shortage of this approach is that it seems unable to test SQL Server high availability group connection. There is not a parameter for configuring MultiSubnetFailover. I tested with an AG listener with database nodes from different subnets and it couldn’t connect.

However, it doesn’t change the fact that this is the easiest way to test SQL Server connection. Hope you find this trick useful!

Assign permission on a certificate for an ApplicationPoolIdentity account

If your web application is running under ApplicationPoolIdentity account, you must have had the headache of configuring permission to this account. The trick of using IIS APPPOOL\Name has never worked for me. In order to find this user in the permission configuration window, I have been running ICACLS commend every time. This post has more detail on both approaches.

Now if your ApplicationPoolIdentity-using-web-application utilizes some certificate to encrypt/decrypt messages, such as a WCF web service with message level security based on certificate, you would have to figure out how to assign permission on this certificate to your ApplicationPoolIdentity user.

It is actually similar with assigning permission to some other file in that way that you can either use the IIS APPPOOL\Name method or using ICACLS command as described in the post mentioned above. However, if the IIS APPPOOL\Name approach does not work for you, ICACLS approach requires a file path in order to add this user account. The cert is usually stored somewhere deep and is under a different name than your original cert, which makes it difficult to be found.

HOW TO FIND THE PATH TO THE CERT? 

First you need a tool called FindPrivateKey.exe from Microsoft. It is funny because you can’t find a download link directly for this executable. It is actually a part of a sample code solution for WCF services. Here is the link to the source codes. Unzip it and compile the project from the folder C:\WF_WCF_Samples\WCF\Setup\FindPrivateKey\. After the compilation, you will have the executable!

This tool can help you find the actual file location of you cert with the cert’s Thumbprint. To find the thumbprint, open Microsoft Management Console.

Image

Add the Certificates snap-in

Image

Image

You should be able to find your cert somewhere

Image

Right click it, select Open. Click on the Details tab in the Certificate dialog. You should be able to find the Thumbprint of your cert.

Image

Now with the thumbprint, run the following command in command line prompt. Note that in the example, I tried to retrieve the cert’s for the local machine. See this page for more details on this tool. 

>FindPrivateKey my localmachine -t ” THUMBPRINT

It will return the folder and name of your cert!

Image

Now a simple ICACLS command can grant the permission needed to our cert.

Image