{{announcement.body}}
{{announcement.title}}

Invoking WCF Service Secured With Basic Authentication Using SoapUI

DZone 's Guide to

Invoking WCF Service Secured With Basic Authentication Using SoapUI

In this post, we will demonstrate how to use the SoapUI API tool to invoke a secured WCF SOAP service.

· Security Zone ·
Free Resource

In this post, we will demonstrate how to use the SoapUI API tool to invoke a secured WCF SOAP service. First, we will create a service where it will be the system under test. Next, we will approach the steps required to invoke the created service while secured by a basic authentication mechanism.

1 WCF Basic Authentication Service

The access to the resource in the service to be implemented will be secured using Basic Authentication transport security mechanisms. One of many provided by the Windows Communication Foundation. This kind of mechanism is used in conjunction with HTTPS to provide confidentiality. 

This service exposes one endpoint that calculates a very big sum. To get started quickly we will use the default template of the WCF Service Application provided in Visual Studio 2019. 

From Menu File, New, then Project or click on Start Page to start a new project. Let’s name the solution and the project to AVeryBigSum_BasicAuthentication

Now you’ll see a couple of files already added to the WCF Service project. We have the option to delete the interface IService1.cs and service Service1.svc file to create new ones. Otherwise, we can rename both files, therefore pay attention to renaming as well as the markup of the Service1.svc file, by right click in it -> View Markup and change to that bellow.

C#
 




xxxxxxxxxx
1


 
1
<%@ ServiceHost Language="C#" Debug="true" 
2
Service="AVeryBigSum_BasicAuthentication.Avbs" CodeBehind="Avbs.svc.cs" %>





view markup


After renaming both files, open the IAvbs.cs, copy the following code and add it to the modified interface.

C#
 




xxxxxxxxxx
1
18


 
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Runtime.Serialization;
5
using System.ServiceModel;
6
using System.ServiceModel.Web;
7
using System.Text;
8
 
          
9
namespace AVeryBigSum_BasicAuthentication
10
{
11
    [ServiceContract]
12
    public interface IAvbs
13
    {
14
 
          
15
        [OperationContract]
16
        long AVeryBS(long[] ar);
17
    }
18
}



In case you chose to delete those files you can add a new interface by right-clicking on the project and Add new item. Select the Interface template and rename it to IAvbs. As well you need to copy the code above and add it to the newly created interface.

The service implements only one operation defined in the interface contract. To implement it, we need to modify the default file created by VStudio or add a new service class Avbs.svc which will implement the above-defined interface.

C#
 




xxxxxxxxxx
1
16


1
using System;
2
/*...*/
3
namespace AVeryBigSum_BasicAuthentication
4
{
5
    public class Avbs : IAvbs
6
    {
7
        public long AVeryBS(long[] ar)
8
        {
9
            long aVeryBigSum = 0;
10
 
          
11
            foreach (long i in ar) aVeryBigSum += i;
12
            
13
            return aVeryBigSum;
14
        }
15
    }
16
}



So far we have defined a service contract, an operation with a sample definition. Now we have to define its endpoints. To add an endpoint, we need to change the configuration file (web.config). Apart from copying and paste, we need to understand the importance of each of these WCF tags.  

1.1 AppSettings

Hence, let's start with the AppSettings element. This element contains custom application settings. The element stores custom application configuration information, such as database connection strings, file paths, XML Web service URLs, or any other custom configuration information for an application.

We use this element to store the Service´s User and Password credentials. The key/value pairs specified in the element are accessed in code using the ConfigurationSettings library in this way ConfigurationManager.AppSettings["AVeryBigSum_User"].

XML
 




xxxxxxxxxx
1


 
1
<appSettings>
2
  <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
3
  <add key="AVeryBigSum_User" value="AVeryBigSum"/>
4
  <add key="AVeryBigSum_Pass" value="12345"/>
5
</appSettings>



Thus, we can change these credentials without the need to rebuild the dynamic link libraries files (DLL) of our project.

Despite the advantage of using the element above, all the magic related to the definition of the service happens in the boundaries of the ServiceModel tag showed next.

1.2 Behaviors

The behaviors tag defines the protocol elements consumed by endpoints and services respectively. The service credentials element is essential to define. It specifies the custom validation mode used in the authentication process. 

XML
 




xxxxxxxxxx
1
14


 
1
<behaviors>
2
      <serviceBehaviors>
3
        <behavior name="DebugModeBehavior">
4
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
5
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
6
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
7
          <serviceDebug includeExceptionDetailInFaults="true"/>
8
          <!--For UserPass Authentication-->
9
          <serviceCredentials>
10
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="AVeryBigSum_BasicAuthentication.ServiceAuthenticator, AVeryBigSum_BasicAuthentication"/>
11
          </serviceCredentials>
12
        </behavior>
13
      </serviceBehaviors>
14
    </behaviors>



Inside service credentials, another important property is defined to specifies the settings for username and password validation. The userNamePasswordValidationMode property sets how the credential is validated. Our service uses a custom class to validate the credentials. This class AVeryBigSum.ServiceAuthenticator can be found in the AVeryBigSum project.

1.3 Bindings

 Each endpoint in a WCF service requires a binding to be well-specified. A binding consists of an ordered stack of binding elements, each of which specifies a part of the communication information required to connect to a service endpoint.

As we can see we are using WSHttpBinding. It represents an interoperable binding that supports distributed transactions, secure and reliable sessions. 

XML
 




xxxxxxxxxx
1
15


 
1
 <bindings>
2
      <wsHttpBinding>
3
        <!-- configure wsHttp binding with Transport security mode and clientCredentialType as Certificate -->
4
        <binding name="wsHttpBinding_LargeBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="false" 
5
                 transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="250000000" maxReceivedMessageSize="250000000" messageEncoding="Text" 
6
                 textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
7
          <readerQuotas maxDepth="2000000" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
8
          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
9
          <!--For UserPass Authentication-->
10
          <security mode="TransportWithMessageCredential">
11
            <message clientCredentialType="UserName" establishSecurityContext="false"/>
12
          </security>
13
        </binding>
14
      </wsHttpBinding>
15
    </bindings>



WSHttpBinding uses the HTTP transport and provides message security, transactions, reliable messaging, and WS-Addressing, either enabled by default or available through a single control setting.

Inside the WSHttpBinding element, we define the security mode as TransportWithMessageCredential. The transport determines the actual mechanism that provides the transport-level security. For HTTP, the mechanism is Secure Sockets Layer (SSL) over HTTP (HTTPS); 

1.4 Service

Finally, at the service element, we define endpoints, exposing the service metadata. It is useful to publish metadata like Web services Description Language (WSDL) document that describes all methods and data types employed by a service. It will be used by SoapUi, to retrieve and invoke all serviceable endpoints.

XML
 




xxxxxxxxxx
1


 
1
<services>
2
      <service behaviorConfiguration="DebugModeBehavior" name="AVeryBigSum_BasicAuthentication.Avbs">
3
        <endpoint address="endpointAVeryBigSum_BasicAuthentication" binding="wsHttpBinding"
4
          bindingConfiguration="wsHttpBinding_LargeBinding" name="EndpointAVeryBigSum_BasicAuthentication"
5
          contract="AVeryBigSum_BasicAuthentication.IAvbs" />
6
        <endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_LargeBinding"
7
          name="mexEndpoint" contract="IMetadataExchange" />
8
      </service>
9
    </services>



1.5 Custom Validator Class

The custom validator extends the UserNamePasswordValidator class and overrides the method to ValidateThis validator is defined in Service Behaviors as default Authorization manager, as showed above in the behavior section. This class compares the information received by the client call to those defined in the AppsSetting/WebConfig element.

C#
 




xxxxxxxxxx
1
26


1
using Microsoft.IdentityModel.Tokens;
2
using System;
3
using System.Collections.Generic;
4
using System.Configuration;
5
using System.IdentityModel.Selectors;
6
using System.Linq;
7
using System.ServiceModel;
8
using System.Web;
9
namespace AVeryBigSum_BasicAuthentication
10
{
11
    public class ServiceAuthenticator : UserNamePasswordValidator
12
    {
13
        public override void Validate(string userName, string password)
14
        {
15
 
          
16
            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
17
 
          
18
                throw new SecurityTokenException("Username and password required");
19
 
          
20
            if (!(userName == ConfigurationManager.AppSettings["AVeryBigSum_User"] && password == ConfigurationManager.AppSettings["AVeryBigSum_Pass"]))
21
 
          
22
                throw new FaultException(string.Format("Wrong username ({0}) or password ", userName));
23
 
          
24
        }
25
    }
26
}



By the way, to this class to work properly, we need to add two external libraries to the project. We can do this by right click on the project -> Manage NuGet Packages, browse for Microsoft.IdentityModel.Logging and Microsoft.IdentityModel.Tokens packages and add both.

Now that we have defined the endpoint, next, we will host the service in the local development server.

1.6 Deploy and Run the Service

  1. To host our service in IIS, right-click on the project, and go to Properties. In properties->window select Web tab.
  2. Now under Servers on Web settings, you’ll see the following details, change the “IIS Express” to “IIS Server”.
  3. Now Click on Create Virtual Directory with Visual Studio running As Administrator. You’ll get a message The Virtual directory was created successfully! Otherwise, you’ll receive an error message and you need to ensure that you launch the Visual Studio as Administrator.

Now press F5 and your application will be up and running on the IIS server instead of your IIS express.

2 Invoking the Service

We created a basic authentication service to be invoked using SoapUI. Now we will demonstrate step by step how to use this tool to successfully invoke this kind of service.

2.1 Create New SOAP project

Firstly we need to create a SoapUI project and in the "Initial WSDL", add the URL of the WSDL service created at the beginning. Also, add your desired project name. 

A new project is generated with a sample request for the service.

SOAP

2.2 Authentication and Security Related Settings Tab

After create successfully the new SoapUI project, collapse until the request´s endpoint. Now double click the request or right-click of the mouse to open the Show Request Editor. Navigate to the Auth (Basic) tab in the bottom corner, surround toward a green circle.

Authorize

In the Authorization dropdown list, select Basic. It is the same as the service created before. Following, SoapUI shows a form when we can insert the Username and the Password service credentials "AVeryBigSum", "12345" respectively.

2.3 WS-Addressing related settings tab

Navigate to the WS-A Configurations tab, and enable the WS-A addressing, that defines two interoperable constructs typically provided by transport protocols (endpoint references) and messaging systems (message information headers). These constructs normalize this underlying information into a uniform format that can be processed independently of transport or application.

To instruct the service to process the crucial element in the header, we need to specify to TRUE the "Must understand"  configuration. The header contains crucial data to process, and the recipient must process the headers. If the service, can't process the header or didn't receive the header, an error will be raised.

WS-A

Also, SOAPUI allows us to enable the Add default wsa: To and Add default wsa: Action configuration. The Add default wsa: To provides the value for the destination property. The default anonymous value for this property is "http://www.w3.org/2005/08/addressing/anonymous". In the above example, the default wsa: Action, wsa: To and wsa: MessageId headers have been enabled, so when we send the request we can see them in the raw request view.

2.4 WS-Reliable Message Related Settings Tab

To ensure reliable communication between two systems we enable the WS-Reliable Message specification. The aim of this is to ensure that messages are transferred properly from the sender to the receiver in the presence of network failures. As well we select the latest version of this specification for this demonstration.

WS-RM

2.5 Request Properties

Finally in the left corner Request Properties -> WSS-Password Type we select PasswordText. WSS-Password Type is a concept that will outline if the password in the XML payload is plain text or digest. For Digest, you can use the Require Ws-Security Password Digest Credentials which is a one to one relationship of the user to assertion as we need to know the password. For Plain text, you can use the WS-Security UsernameToken Profile Credentials.

PasswordText

Conclusion

In this post, we demonstrate how to configure a SoapUI project to invoke a WCF Basic Authentication service. We used the secured service created to serve as a system under test. 

The sample of the WCF service and the SoapUi project is accessible from the GitHub repository; to download it, please follow this link.

Topics:
basic authentication, security, soap, soapui, tutorial, wcf

Published at DZone with permission of Jailson Evora . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}