@scsiworm

Как пройти аутентификацию на основе сертификата по SSL в Apache Axis на C#?

Доброго времени суток!

Имеется удаленный сервис на Apache Axis (находится в домене А) запросы к которому необходимо подписывать с помощью сертификата. Необходимо написать клиента на C# (находится в домене Б и никак не связан с доменом А) который бы отправлял данный запрос от имени пользователя домена А, сертификат которого выгружен в *.P12 (с приватным ключом). Полученный сертификат прогрузил в хранилище винды и оттуда его беру.

По мануалу к сервису можно обратится
1) через HTTP - подписать сам SOAP запрос (в секции header),
2) через транспортный уровень HTTPS.

В обоих случаях получаю ответ от сервиса - (403)Forbidden. Причем ошибка явно на уровне первичной аутентификации, т.к. согласно мануалу отсутствие прав на выполнение имеет другой формат ошибки.

Люди, кто поддерживают сервис на домене А говорят что ssl handshake вроде проходит, но пользователь не определяется. Эти люди мне сертификат и давали.

Подскажите плз, в каком мне направлении копать? может какие то махинации с сертификатом надо произвести?

Вариант 1. Пример запроса через 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>

Соответствующий код C#:
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;
}


Вариант 2. А так я пытался отправить через 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;
        }
  • Вопрос задан
  • 1242 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы