S
S
scsiworm2016-03-21 23:35:48
SOAP
scsiworm, 2016-03-21 23:35:48

How to pass certificate-based authentication over SSL in Apache Axis in C#?

Good day!
There is a remote service on Apache Axis (located in domain A) requests to which must be signed using a certificate. It is necessary to write a client in C# (located in domain B and not connected to domain A in any way) that would send this request on behalf of a user in domain A, whose certificate is uploaded in *.P12 (with a private key). The received certificate was uploaded to the Windows store and from there I take it.
According to the manual, the service can be accessed
1) via HTTP - sign the SOAP request itself (in the header section),
2) via the HTTPS transport layer.
In both cases, I get a response from the service - (403)Forbidden. Moreover, the error is clearly at the level of primary authentication, because. According to the manual, the lack of execution rights has a different error format.
People who support the service on domain A say that ssl handshake seems to pass, but the user is not determined. These people gave me a certificate.
Tell me, in which direction should I dig? maybe some fraud with the certificate should be done?
Option 1. Example request via HTTP (SignXML):

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
        <ds:Reference URI="#Body">
          <ds:Transforms>
            <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" />
          </ds:Transforms>
          <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <ds:DigestValue>6kkrzRtR.....</ds:DigestValue>
        </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>V2Wod0G.............</ds:SignatureValue>
      <ds:KeyInfo>
        <ds:X509Data>
          <ds:X509Certificate>MIICxTCCAa2gAw.................</ds:X509Certificate>
        </ds:X509Data>
        <ds:KeyValue>
          <ds:RSAKeyValue>
            <ds:Modulus>1k6698yXPa9b..........</ds:Modulus>
            <ds:Exponent>AQAB</ds:Exponent>
          </ds:RSAKeyValue>
        </ds:KeyValue>
      </ds:KeyInfo>
    </ds:Signature>
  </soapenv:Header>
  <soapenv:Body Id="Body">
    ...
  </soapenv:Body>
</soapenv:Envelope>

Relevant C# code:
public string postXMLData(string destinationUrl, XElement operationXml, string certName)
{
  ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

  var xml = XmlSecurity.GenerateSoapXml(operationXml);
  var signXml = XmlSecurity.SignRequest(xml, certName);

  HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destinationUrl);

  request.Headers.Add("SOAPAction: \"\"");
  request.ContentType = "text/xml; charset=\"utf-8\"";
  request.Accept = "text/xml";
  request.Method = "POST";

  try
  {
    using (var requestStream = request.GetRequestStream())
    {
      signXml.Save(requestStream);
    }

    var response = (HttpWebResponse)request.GetResponse();
    if (response.StatusCode == HttpStatusCode.OK)
    {
      using (Stream responseStream = response.GetResponseStream())
      {
        return new StreamReader(responseStream).ReadToEnd();
      }
    }
  }
  catch (Exception ex)
  {
    return ex.ToString();
  }

  return null;
}

Option 2. And so I tried to send via HTTPS:
public string postXMLData(string destinationUrl, XElement operationXml, string certName)
        {
            ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

            var xml = XmlSecurity.GenerateSoapXml(operationXml);

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destinationUrl);

            request.Headers.Add("SOAPAction: \"\"");
            request.ContentType = "text/xml; charset=\"utf-8\"";
            request.Accept = "text/xml";
            request.Method = "POST";

            request.Credentials = new NetworkCredential("Login", "Pass", "Domain");
            request.ClientCertificates.Add(XmlSecurity.GetCertificateBySubject(certName));

            try
            {
                using (var requestStream = request.GetRequestStream())
                {
                    xml.Save(requestStream);
                }

                var response = (HttpWebResponse)request.GetResponse();
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        return new StreamReader(responseStream).ReadToEnd();
                    }
                }
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }

            return null;
        }

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question