From Consuming SOAP service in SoapUI to consuming it with CSHARP

Claudia Murialdo 1 Reputation point
2022-10-15T14:00:40.893+00:00

Hello, I have a project in SOAP UI that consumes a soap service and works well. The service has ws-security and addressing.
I'm trying to do the same, programmatically with csharp and WCF. I have tried many configurations at app.config but it keeps failing. It would be helpful if you can provide me with a guide for the correspondence between soap ui and WCF configuration.

Here is the soap ui project:

250778-iniciosolicitud-soapui-projecttest.xml
And here is the configuration I'm trying at app.config for my c# console application that consumes the same service.
250792-atestiniciosolicitudmainexeconfig.xml

And this is the method BeforeSendRequest of my custom binding to configure Adressing which seems to work well.

public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
{
if (gxLocation != null && gxLocation.WSAddressing != null)
{
if (gxLocation.WSAddressing.Action != null)
request.Headers.Action = gxLocation.WSAddressing.Action;
if (gxLocation.WSAddressing.FaultTo != null)
request.Headers.FaultTo = GxHelpers.BuildEndpointAddress(gxLocation.WSAddressing.FaultTo);
if (gxLocation.WSAddressing.From != null)
request.Headers.From = GxHelpers.BuildEndpointAddress(gxLocation.WSAddressing.From);
if (!string.IsNullOrEmpty(gxLocation.WSAddressing.MessageID))
request.Headers.MessageId = new UniqueId(gxLocation.WSAddressing.MessageID);
if (!string.IsNullOrEmpty(gxLocation.WSAddressing.RelatesTo))
request.Headers.RelatesTo = new UniqueId(gxLocation.WSAddressing.RelatesTo);
if (gxLocation.WSAddressing.ReplyTo != null)
request.Headers.ReplyTo = GxHelpers.BuildEndpointAddress(gxLocation.WSAddressing.ReplyTo);
if (!string.IsNullOrEmpty(gxLocation.WSAddressing.To))
request.Headers.To = new Uri(gxLocation.WSAddressing.To);

        }  
        Guid guid = Guid.NewGuid();  
        return guid;  
    }  
.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,451 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,364 questions
.NET Runtime
.NET Runtime
.NET: Microsoft Technologies based on the .NET software framework.Runtime: An environment required to run apps that aren't compiled to machine language.
1,130 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Jiayao Wu-MSFT 186 Reputation points Microsoft Vendor
    2022-10-17T06:07:02.213+00:00

    Hi @Claudia Murialdo ,

    In general, the wcf service can be configured in the.NET client by doing the following:

    1. Create a new project and add the url to the wsdl. A new project is generated with a sample request for your service.
    2. Use right click of the mouse in the project to open the “Project view”.
    3. Navigate to the “WS-Security Configurations” tab.
    4. Select the “Keystores” tab and add the certificate with private key so you can sign the request.
    5. Go to the “Outgoing WS-Security Configurations” and add a new configuration.
    6. Add in the newly created configuration a “Signature”.
    7. Configure the keystore that you’ve added.
    8. Use “Binary Security Token” as Key Identifier Type.
    9. Set the right Algorithms that you have configured in the service. For better security the default use SHA1 is not a best practice anymore. You could change the configuration in the WCF service to algorithmSuite=”Basic256Sha256Rsa15″ in the message element of the binding. This article makes the case. Then use RSA-SHA256 for signature algorithm, XML-EXC-C14n# for Signature Canonicalization and XMLENC#SHA256 for the Digest Algorithm.
    10. Check the “Use single certificate” checkbox.
    11. By default SoapUI signs the whole request but that isn’t the default by WCF so you have to set the parts that you want to sign. So add as Name “To”, Namespace “http://www.w3.org/xxx/xxx/xx” (this is a example ,put yours in it) and set Encode to “Element”.
    12. Add a timestamp and set it to 300. Use milisecond precision.
    13. Check the order on the left. So first signature and then timestamp.

    And if you want to view information about WS-Security, refer to the following page.

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Claudia Murialdo 1 Reputation point
    2022-10-18T18:13:16.17+00:00

    Update:
    I got the right configuration with the following custom bindings.
    The only problem is that the body does not get encrypted as expected, given the messageProtectionOrder="EncryptBeforeSign". It seems to be a bug of WCF.

    <customBinding >
    <binding name="gxWsSoapBinding">
    <textMessageEncoding messageVersion="Soap12WSAddressing10" writeEncoding="utf-8" />
    <security authenticationMode="MutualCertificate"
    defaultAlgorithmSuite="Basic128"
    messageProtectionOrder="EncryptBeforeSign"
    securityHeaderLayout="Lax"
    includeTimestamp="false"
    messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
    </security>
    <httpsTransport />
    </binding>
    </customBinding>

    .......

    <endpointBehaviors>
    <behavior name="gxCustomBehaviorConfig">
    <clientCredentials>
    <!--Specify a certificate to use for authenticating the client SIGNATURE.-->
    <clientCertificate findValue="privatekey.client" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" >
    </clientCertificate>
    <!--Cert used for encryption-->
    <serviceCertificate >
    <defaultCertificate storeLocation="LocalMachine" storeName="My" findValue="publickey.service.com" x509FindType="FindBySubjectName" />
    <authentication certificateValidationMode="None" revocationMode="NoCheck"/>
    </serviceCertificate>
    </clientCredentials>
    </behavior>
    </endpointBehaviors>