Search code examples
web-serviceswcfsslsoapsoa

What is the ideal way to send a client certificate and an Authorization header with Soap request


I have this ASP.Net Web API application which calls a web service. Right now (development environment) The web service (SOAP) and my ASP.net application are in internal network. In production, the web api application will be in public internet and SOAP service will be in the internal network.

In production we use CA SOA Gateway which validate every service call and redirect request to Internal web service. The Gateway application is in HTTPS and internal web service is in HTTP.

The CA SOA gateway requires 2 factor authentication,

  • Authentication header (OAuth Basic authorization)
  • client certificate

I have followed this article to include an authorization HTTP header with every service request. It works fine.

I'm using the wcf client configuration (in web.config) to include a client certificate with the request (< security mode=transport />).

I want to add the client certificate from a physical location instead of a certificate store. I followed this article to attach client certificate from a file, but it didn't work for me because I'm using .Net 4.6.1 and I dont have System.ServiceModel namespace to use the DevAge.ServiceModel code (from the given example code).

Questions:

  • Is there a better way to include HTTP Header with every service request?
  • Is there a way to include client certificate from a file instead of certificate store?

Note: The Authorization header and client certificate are only for the verification of SOA Gateway they are not required for web service.

Appreciate your help.


Solution

  • About the Headers, you can also implement the IClientMessageInspector interface to add a header for every call. Something like this:

    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request,  System.ServiceModel.IClientChannel channel)
    {
       request.Properties.Add(HttpRequestMessageProperty.Name, new HttpRequestMessageProperty { .... });
    
    }
    

    There's a similar question with good examples here: How to add a custom HTTP header to every WCF call?

    And here is another good example that I've used: Authentication using HTTP Authorization Header in WCF SOAP API

    More about the IClientMessageInspector: MSDN

    About the certificate, you can add certificate from path when you instantiating the client endpoint, like this:

    var endpointIdentity = EndpointIdentity.CreateX509CertificateIdentity(new X509Certificate2(@"c:\cert\mycertificate.pfx", "password"));
    var endpoint = new EndpointAddress(new Uri("http://dns/service.svc"), endpointIdentity);
    

    Or add to the client, like this:

    var client = new YourService("BasicHttpBinding_IServiceInterface");
                client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(@"c:\certifcate.pfx", "password", X509KeyStorageFlags.DefaultKeySet);
    

    Hope it helps.