How to consume third party https wsdl web service in c#

14,927

Thank god, finally i've found a solution after a long research, googling/binging and hard work. Just Recap: Third party web service (coded in Java) with X509 SecurityToken Https certificate consume in .NET.

Yes, we can consume the above service using old technology using WSE 2.0 / WSE 3.0 (Web Services Enhancements) and Latest using WCF. I've just tried using WSE 2.0 it's working as expected but with Error code "WSE464: No policy could be found for this message" still i can able to get see response in try..catch block and use appropriate decrypt XML response message.

Steps followed

  • Install the client given certificate (.pfx)

  • Open Microsoft Management Console (MMC) in run command type mmc → Enter a. File → Add/Remove snap in → Select certificate in list box → Click Add → Select My
    Current User → Finish –> Click Ok.

         b. Select Trusted Root Certification → Expand it → Select Certificate → Right click on           
             Certificate → Select All Tasks → Import → Select your Certificate location and finish the  
              wizard process
    
  • Repeat Step 2 for Local Machine (Local Computer)

  • Install Microsoft WSE (Web Services Enhancements) 2.0 SP3 / WSE 3.0 Note. WSE 2.0/3.0 will support .Net Framework 2.0 only. http://www.microsoft.com/en-in/download/details.aspx?id=23689

  • Create new web application project in Visual Studio Expand project → Right click on Reference → Add Service Reference → Advanced → Add Web Reference → Paste your Service WSDL link in URL text box → Click on Go button (Pointing right arrow) → Since it's https it will show with popup with warning message click Yes until it's stops → Enter Web Reference name and click Add Reference button Right click → Reference → Add reference → Click Browse → \Program Files\Microsoft WSE\v2.0\ → Select “Microsoft.Web.Services2.dll” → Click Add Proxy/Stubbed class generated now → Look for Reference.cs file under Web Reference folder if not visible click Show all files in Solution Explorer. → Open Reference.cs file and Replace “System.Web.Services.Protocols.SoapHttpClientProtocol” with “WebServicesClientProtocol”

        protected void Page_Load(object sender, EventArgs e)
        {
            private static string ClientBase64KeyId = "XPaTfx6Lx8dV/oh6ebOeOo4Xdummy";
            MyService myClient = new MyService();
            try
            {
               SecurityToken signingToken = GetClientToken(false);
               //Get the SoapContext for the SOAP request.
               SoapContext requestContext = client.RequestSoapContext;
    
               // Expire this message one minute after it is sent.
               requestContext.Security.Timestamp.TtlInSeconds = 3600;
    
                // Add the X509 certificate to the WS-Security header.
                requestContext.Security.Tokens.Add(signingToken);
    
                MessageSignature sig = new MessageSignature(signingToken);
    
                requestContext.Security.Elements.Add(sig);
    
                RequestClass request = new RequestClass();
                request.Name =””;
                ResponceClass  responce  = myClient.QueryCsa(request);
            }
            catch(Exception ex)
            {
               lblResultMessage.Text = ex.Message;
            }
    
    
        public static X509SecurityToken GetClientToken(bool selectFromList)
        {
            X509SecurityToken token = null;
    
            // Open the CurrentUser Certificate Store and try MyStore only
            X509CertificateStore store = X509CertificateStore.CurrentUserStore(X509CertificateStore.MyStore);
            if (selectFromList)
            {
                //token = RetrieveTokenFromDialog(store);
            }
            else
            {
                token = RetrieveTokenFromStore(store, ClientBase64KeyId);
            }
    
            return token;
        }
    
       private static X509SecurityToken RetrieveTokenFromStore(X509CertificateStore store, string keyIdentifier)
        {
            if (store == null)
                throw new ArgumentNullException("store");
    
            X509SecurityToken token = null;
    
            try
            {
                if (store.OpenRead())
                {
                    // Place the key ID of the certificate in a byte array
                    // This KeyID represents the Wse2Quickstart certificate included with the WSE 2.0 Quickstarts
                    // ClientBase64KeyId is defined in the ClientBase.AppBase class
                    Microsoft.Web.Services2.Security.X509.X509CertificateCollection certs = store.FindCertificateByKeyIdentifier(Convert.FromBase64String(keyIdentifier));
    
                    if (certs.Count > 0)
                    {
    
                        if (!certs[0].SupportsDigitalSignature ||
                    (certs[0].Key == null))
                        {
                            //MessageBox.Show(
                            //    "The certificate must support digital " +
                            //    "signatures and have a private key available.");
                            //securityToken = null;
                        }
                        // Get the first certificate in the collection
                        token = new X509SecurityToken(((Microsoft.Web.Services2.Security.X509.X509Certificate)certs[0]));
                    }
                }
            }
            finally
            {
                if (store != null)
                    store.Close();
            }
    
            return token;
        }
    

    }

  • Add the following code in in your page and Get ClientBase64KeyId value from X509 Certficate Tool.

  • Start → Program Files → Microsoft WSE 2.0 → X509 Certificate Tool → Select Certificate Location is Local Computer → Sore Name is Personal → Click Open Certificate Button, listed with certificates and select appropriates which is one installed using MMC. Now pick the values from Key Identifier (Based64 Encoded) value and use it below code. If your application is Asp.Net Web application, it may not accessible so click 'View Private Keys File Properties' button and assign appropriate Security permission in the same tool itself.

  • Almost we've done 70% of work. Now it's very crucial part going to do now... Yes we're going to apply Policy details.This is all about Security Policy related to X509 Certificate which defines about what part it's going to Sign (Signature), Encryption, Integrity, Confidentiality and so on. Don't panic we have helper called WSE 2.0 Tool, Yes chumma :) try it Start → Program Files → Microsoft WSE 2.0 → Configuration Editor → File → Open → Point to Web.config from your application

  • General => Check both the Check Boxes

  • Security, Routing and Customized Filters => They are not called me:) So Leave It.

  • Policy => Very Important. 1. Check Enable Policy 2.Click Add → Name
    it / Enter any name → Next → Leave it default (Secure Client
    Application) → (Default) Next → Next → (Default: X509 Certificate) → Next → Select Certificate → Select appropriate certificate from the
    list → Ok → Next → Finish

  • TokenIssuing => Leave it

  • Diagnostics => Check it appropriate check boxes for tracing and
    logging purpose

  • File → Save → Close it :)

  • Now one would've created policyCache.config which is referenced in Web.config file. Here we have add our HTTPS service URL in . Done

This is achieved by WSE 2.0. Yes i know this is old technology. I am trying to consume with WCF as Client... I will post it next session....

:) Happy Programming :) JaiSankar

Share:
14,927
Jaisankar
Author by

Jaisankar

Updated on June 04, 2022

Comments

  • Jaisankar
    Jaisankar almost 2 years

    In SoapUI tool I've configured .Jks file with Outgoing WS-Security Configurations Signature is BinarySecurityToken and algorithm is CanonicalizationMethod and SignatureMethod it is working perfectly.

    Now I try to consume from C# code as below :

    SprintApiService.QueryCsaPortTypeClient client = new QueryCsaPortTypeClient();
    
    ClientCredentials ce = new ClientCredentials();
    string fileName = Server.MapPath("");
    fileName = fileName + "/test-01.pfx";
    ce.ClientCertificate.Certificate = new X509Certificate2(fileName, "tag123");
    var val = ce.ClientCertificate.Certificate.GetSerialNumber();
    ce.ClientCertificate.SetCertificate("CN=jaitest-01, OU=TPA, OU=BMP, OU=Projects, O=Sprint, C=us", StoreLocation.CurrentUser, StoreName.TrustedPeople);
    
    System.IdentityModel.Selectors.SecurityTokenManager sTokenMgr = ce.CreateSecurityTokenManager();
    //var sTokenMgr = ce.CreateSecurityTokenManager();
    

    But I could not succeed. I am always getting "Rejected by Client (Policy)" please help me.

    This is sample request which is created in SoapUI tool :

    <wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
             <wsu:Timestamp wsu:Id="Timestamp-c55ce328-af36-4b0f-97d8-3bab57ee6a46" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
                <wsu:Created>2014-02-18T12:27:52Z</wsu:Created>
                <wsu:Expires>2014-02-18T12:32:52Z</wsu:Expires>
             </wsu:Timestamp>
             <wsse:BinarySecurityToken wsu:Id="SecurityToken-1da2e6b0-3a0d-4943-bcae-de0805d9c4c5" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">MIIDmTCCAwKgAwIBAgIERxqCLDANBgkqhkiG9w0BAQUFADAeMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGU3ByaW50MB4XDTExMDgwMjIwMDc0OVoXDTE4MDgwNDA0MDAwMFowYjELMAkGA1UEBhMCVVMxDzANBgNVBAoTBlNwcmludDERMA8GA1UECxMIUHJvamVjdHMxDDAKBgNVBAsTA0JNUDEMMAoGA1UECxMDVFBBMRMwEQYDVQQDEwpzcHJpbnQtbXNvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCG2yDWPQBNG9bjt+sVMzlaooX3jON7tOoqtIxPkXl7XCEvbzZpXL2tYtHXqxVfPo9h1weulbj0dE4LlVjlTjzW4upBI92StqDVYdzTLvZWie1fEslIThHDoX7paQpnrSew3TZ6fk4qVnF4h44J/rLnFt3jLEO6IyRhddganpoOowIDAQABo4IBnjCCAZowCwYDVR0PBAQDAgWgMCsGA1UdEAQkMCKADzIwMTEwODAyMjAwNzQ5WoEPMjAxODA4MDQwNDAwMDBaMBEGCWCGSAGG+EIBAQQEAwIFoDCB5AYDVR0fBIHcMIHZMDagNKAypDAwLjELMAkGA1UEBhMCVVMxDzANBgNVBAoTBlNwcmludDEOMAwGA1UEAxMFQ1JMMjkwgZ6ggZuggZiGSmxkYXA6Ly9jYXg1MDAxLnNwcmludC5jb206Mzg5L289U3ByaW50LGM9VVM/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdD9iYXNlhkpsZGFwOi8vY2F4NTAwMi5zcHJpbnQuY29tOjM4OS9vPVNwcmludCxjPVVTP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZTAfBgNVHSMEGDAWgBRFTY2yujBdccYEb58W/Dt7VY3NHzAdBgNVHQ4EFgQUzUEoNuQ9ummaIU8K6h28izpV2YUwCQYDVR0TBAIwADAZBgkqhkiG9n0HQQAEDDAKGwRWNy4xAwIDKDANBgkqhkiG9w0BAQUFAAOBgQCTDjwpnYdx9JZpBrIwm4qIF4tZmXCCUIBEcoER1oUw/NSdgbbRjpU5AxUR/aK1K3taa27HS+WBQYTeMw+Y/LFhp8m+UjHBx/O1kfk4JAz201Kk0HeGgFvt9sscLfK8YD0aavdDJ6Z0rMpHBlcv8VQ7P+1zqJLay3TY+atl9wuD/Q==</wsse:BinarySecurityToken>
             <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
                <SignedInfo>
                   <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                   <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                   <Reference URI="#Timestamp-c55ce328-af36-4b0f-97d8-3bab57ee6a46">
                      <Transforms>
                         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                      </Transforms>
                      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                      <DigestValue>8H8usvOvRYPwOKHVHdOXO6Y3Cz4=</DigestValue>
                   </Reference>
                   <Reference URI="#Body-db900962-5b93-4a49-a70a-a1745bed8255">
                      <Transforms>
                         <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                      </Transforms>
                      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                      <DigestValue>54u/0PxaY+S7RigxrisF2Chnplc=</DigestValue>
                   </Reference>
                </SignedInfo>
                <SignatureValue>HC10RHq8lweC1KLGAzw1pxjju5LbWASn5GUCxane36DqUxaXQQnBrF0fyBkpI70H+ncrYaO00sxVd1QWnLfYxzl/YEWfHus/qObmFckRnNsEnx9MV5ejHhntbXdzIc9RFbXoFGPcoEGAsKoUbeOi7UWKbofzATG6VMlKhLFz01k=</SignatureValue>
                <KeyInfo>
                   <wsse:SecurityTokenReference xmlns="">
                      <wsse:Reference URI="#SecurityToken-1da2e6b0-3a0d-4943-bcae-de0805d9c4c5" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
                   </wsse:SecurityTokenReference>
                </KeyInfo>
             </Signature>
    </wsse:Security>      
    

    Thanks...

  • Cannon
    Cannon about 9 years
    Can you post the url for next post with WCF. Or if you have sample code or blog posted somewhere with code. That will be really helpful.