Creating a Client in C# Using WCF

This section explains how to create a WCF web service client for the AAA Server 6.8 SKI Connector service.

Generate the Web Service Client Files

Use the following command line to run svcutil.exe and generate the required web service client files:

  • A .cs file with the necessary client structures and functions.

  • An XML .config file defining the service configuration.

svcutil.exe /language:cs /out:<output_path>\generatedProxy.cs /config:<output_path>\app.config <wsdl_path>\ActivCardSKIConnectorV2.wsdl

Where:

  • <output_path> points to the folder where the generated files are to be stored.

  • <wsdl_path> points to the folder of the .wsdl file.

Note: Changing the WSDL filename modifies the generated filenames and content.

Configure the Web Service Client

Prerequisites: The .NET framework must be installed (the sample uses.NET 4.5).
  1. Include the generated .cs file in the project.

  2. The generated .cs file contains a class in charge of generating an instance of the client. In this sample, this is the ActivCardSKIConnectorV2SoapClient class.

  1. To create a client, an instance of this class must be generated as follows:

Copy
ActivCardSKIConnectorV2SoapClient client = null;
client = new ActivCardSKIConnectorV2SoapClient();
  1. If you want to use the app.config file to define the binding and endpoint URI, include the generated .config file in the project.

  2. Alternatively, you can configure the service directly in the code (as in the sample). To do so, add the following variables:

    • Uri skiConnectorUri to store the endpoint URI.
    • For AAA Server 6.8, the service endpoint URI should be as follows:

      http://<hostname>:<port>/ws/ActivCardSKIConnectorV2

    • EndpointAddress skiConnectorEndpoint to store the skiConnectorUri.
    • WSHttpBinding skiConnectorBinding to configure the web service binding.

    Note: If you are not using SSL (the sample default), set the skiConnectorBinding security mode to 'none'.
  1. Modify the client generation code as follows:

Copy
skiConnectorUri = new Uri("http://<hostname>:<port>/ws/ActivCardSKIConnectorV2");
skiConnectorBinding = new WSHttpBinding();
skiConnectorBinding.Security.Mode = SecurityMode.None; 
skiConnectorEndpoint = new EndpointAddress(skiConnectorUri);
ActivCardSKIConnectorV2SoapClient client = null;
client = new ActivCardSKIConnectorV2SoapClient(    skiConnectorBinding,                                     skiConnectorEndpoint);
  1. To test the client configuration and connection, it is recommended that you use a simple function such as getVersion().

  2. If getVersion() returns nothing or indicates an error, the endpoint URL might be wrong or using an invalid format.

Note: If the ActivID SKI Connector is using SSL, you also need to Configure the Sample for SSL.

Use the ActivID SKI Connector Functions

  1. To use the ActivID SKI Connector functions, call the corresponding methods of the client with the required variables.

  2. For further information about the method names and input/output variables, refer to ActivID SKI Connector Service API Functions.

  1. As most functions can only be used with a valid login handle, retrieve it using the Login() function before performing any other operation.

  2. Instantiate and fill a single structure parameter for the inputs.

  3. These structures are declared in the generated header file and should be named _<function_name>In.

  1. If the returned value is a structure, it should one defined in the generated .cs file.

The output variables of the SKI Connector are the returned values of the generated functions.

Close the Service

  1. Before closing the service, it is recommended that you use the Logout() function to invalidate the login handle.

  2. If you do not, it is only invalidated after a defined time (10 minutes).

  1. Use the Close() function to close the web service client:

client.Close();

Configure the Sample for SSL

This section explains how to configure the sample for SSL if the ActivID SKI Connector is using a secured connection.

You can either update the App.config file of the project (as illustrated below) or make the required modifications directly in the C# code.

Prerequisites:  
  • To use SSL with the ActivID SKI Connector, you must import a client certificate into the certificate store of the local machine.

  • During the AAA Server setup, you can generate two certificates used for the AAA SKI Connector service (SKIConnector.p12) and client (WHD.p12). These certificates are generated in the AAA Server <installdir>\Certificates directory.

  • Modify the endpoint URL to use HTTPS instead of HTTP.

  1. Define the following elements in the App.config file:

    • A binding configuration that sets the security mode to Transport and requires the use of the client Certificate.
    • A behavior configuration that defines the following clientCertificate credentials:
      • storeLocation – LocalMachine
      • storeName – My
      • x509FindType – how to search for a certificate (by thumbprint, serial number, subject name etc).
      • findValue – the value to be found (for example, certificate_thumbprint).
    • An endpoint configuration containing the:
      • Endpoint URL
      • Binding defined above
      • Behavior defined above
  1. Remove any C# code that might override the elements defined in the App.config file.

Note: To establish the SSL trust relationship with the certificates generated by the AAA Server setup, a command has been added in the C# code of the client sample to avoid verification of the server certificate.

Example of the App.config file configured for SSL:

Copy
<?xml version="1.0" encoding="utf-8"?>
<configuration>
     <system.serviceModel>
        <!-- behavior configuration -->
        <behaviors>
          <endpointBehaviors>
            <behavior name="customBehavior">
              <clientCredentials>
                <!-- Endpoint configuration -->
                <clientCertificate
                  findValue="<certificate_thumbprint>"
                  x509FindType="FindByThumbprint"
                  storeLocation="LocalMachine"
                  storeName="My" />
                <serviceCertificate>
                <authentication
                  certificateValidationMode="None"
                  revocationMode="NoCheck" />
                </serviceCertificate>
              </clientCredentials>              
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <!-- Binding configuration -->
        <bindings>
            <wsHttpBinding>
                <binding name="ActivCardSKIConnectorV2Soap">                   
                   <security mode="Transport">
                     <transport clientCredentialType="Certificate"/> 
                     <message clientCredentialType="Certificate" />
                   </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <!-- Endpoint configuration -->
        <client>
          <endpoint     
                  address="http://localhost:8200/ws/ActivCardSKIConnectorV2"
                  binding="wsHttpBinding" bindingConfiguration="ActivCardSKIConnectorV2Soap"
                  contract="ActivCardSKIConnectorV2Soap" name="ActivCardSKIConnectorV2PortImpl"
                  behaviorConfiguration="customBehavior">
          </endpoint>              
        </client>        
    </system.serviceModel>
</configuration>

Error Cases

With the WCF framework, all client function calls might throw an exception if the web service call did not perform correctly. Therefore, you need to wrap each function call in a try-catch.

In addition, most functions have a returned value (often a boolean) indicating if the operation was successful.

Implementation Example

Copy
try
{
     int nTimeout = 10 * 60 * 1000; /* setting a 10 minutes timeout */
     LoginIn loginInParameters = new LoginIn();    
     loginInParameters.LoginInUid = "<admin_uid>";
            loginInParameters.LoginInPwd = "<admin_pwd>";
     loginInParameters.LoginInTimeout = nTimeout;
          
            long hLogin = client.Login(loginInParameters);      
}
catch (Exception ex)
{
     Console.WriteLine("ERROR: Login webservice call failed: {0}", ex.Message);
       // Handle error case
}
if (hLogin > 0) Console.WriteLine("Login succeeded.");
else
{
Console.WriteLine("ERROR: invalid credentials.");
       // Handle error case
}