C#发送使用X.509证书签名的SOAP消息

时间:2016-04-28 10:59:13

标签: c# web-services ssl soap soapui

我正在尝试发送一个需要X.509证书的SOAP服务。

Soap UI中,我在SSL settings中设置了证书路径和密码,在请求窗口中输入信封,点击提交并获得结果。

在C#中它变得复杂,主要是因为我对这个东西很新。所以首先我尝试使用Send and Receive a SOAP Message By Using the SoapClient and SoapService Classes指南编写一个简单的消息发送方法,它的工作原理。

下一步是签署(我猜)带有证书的SOAP消息,还有一个指南,至少是一个Sign a SOAP Message Using an X.509 Certificate指南,所以现在我有一个类/方法可以发送SOAP消息和可以签署SOAP消息的类/方法。

但我不知道如何实际签名,我的代码看起来像这样:

public class SOAPTest
{
    public static string Call(string argsUrl, string requestAction, string argsXml)
    {
        Uri destination_uri = new Uri(argsUrl);
        EndpointReference destination = new EndpointReference(destination_uri);
        SoapEnvelope envelope = new SoapEnvelope();

        envelope.LoadXml(argsXml);

        // The destination variable is the EndpointReference 
        // for the Web service.
        TcpClient client = new TcpClient(destination);

        SoapEnvelope returnEnvelope = client.RequestResponseMethod(envelope);
        // The envelope that is returned is the response data.

        return returnEnvelope.OuterXml;
    }
}

我有Sign a SOAP Message Using an X.509 CertificateCreate a Custom Policy Assertion that Secures SOAP Messages中提到的所有类:CustomSecurityAssertion,CustomSecurityServerInputFilter,CustomSecurityServerOutputFilter,CustomSecurityClientInputFilter和CustomSecurityClientOutputFilter,最后一个看起来像这样,据我所知有SecureMessage方法我需要用来签名信封:

class CustomSecurityClientOutputFilter : SendSecurityFilter
{
    SecurityToken clientToken;
    SecurityToken serverToken;

    public CustomSecurityClientOutputFilter(CustomSecurityAssertion parentAssertion)
        : base(parentAssertion.ServiceActor, true)
    {
        // Get the client security token.
        clientToken = X509TokenProvider.CreateToken(StoreLocation.CurrentUser, StoreName.My, "CN=B2B");

        // Get the server security token.
        serverToken = X509TokenProvider.CreateToken(StoreLocation.LocalMachine, StoreName.My, "CN=B2B");
    }

    public override void SecureMessage(SoapEnvelope envelope, Security security)
    {
        X509SecurityToken signatureToken = GetSecurityToken("CN=B2B");
        if (signatureToken == null)
        {
            throw new Exception("Message Requirements could not be satisfied.");
        }

        // Add the security token.                
        security.Tokens.Add(signatureToken);
        // Specify the security token to sign the message with.
        MessageSignature sig = new MessageSignature(signatureToken);

        security.Elements.Add(sig);

    }

    public X509SecurityToken GetSecurityToken(string subjectName)
    {
        X509SecurityToken securityToken = null;
        X509Store store = new X509Store(StoreName.My,
          StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly);
        try
        {
            X509Certificate2Collection certs =
                store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName,
                subjectName, false);

            X509Certificate2 cert;
            if (certs.Count == 1)
            {
                cert = certs[0];
                securityToken = new X509SecurityToken(cert);
            }
            else
                securityToken = null;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        finally
        {
            if (store != null)
                store.Close();
        }
        return securityToken;
    }
}

我如何"连接"这两个并得到我在Soap UI中得到的相同结果?

我是否至少在尝试签署邮件时做正确的事情?如果我尝试按原样运行我的项目,则会收到以下错误消息:

  

请求已中止:无法创建SSL / TLS安全通道。

但如果我提供错误的证书名称,我会收到错误:

  

基础连接已关闭:发送时发生意外错误。

所以看起来SOAP消息签名有效,但是服务器仍然拒绝连接,但是使用Soap UI和相同的证书以及相同的SOAP信封一切正常,没有问题,有什么建议吗?

0 个答案:

没有答案