使用IClientMessageInspector时,如何检测“元素”的原因是无效的XmlNodeType错误?

时间:2014-02-06 16:19:39

标签: xml web-services digital-signature

我通过第三方网络服务发送一些数据。我发送的数据必须先签名,所以我的计划是正确设置的,其中包含XML的SOAP消息如下:

  1. 构建我需要发送到Web服务的对象。
  2. 附加我的IClientMessageInspector实例以对反序列化对象进行签名
  3. 使用XmlReader将签名的xml添加到将要发送到Web服务主体的消息中
  4. 发送消息并获利:)
  5. 但是这没有用,因为在将消息发送到Web服务之前会引发以下异常:'Element' is an invalid XmlNodeType

    以下是用于创建和签署消息的代码块:

    创建将转换为SOAP消息的对象:

    Test.item ItemToSend = new Test.item();
    
    ItemToSend.id = "uniqueNodeId";
    ItemToSend.pid = "VSID000000000113";
    ItemToSend.customData = "correlationData";
    ItemToSend.postbackUrl = "does not matter";
    ItemToSend.userInformation = new Test.userInformation[]
    {
       Test.userInformation.id,
       Test.userInformation.firstName,
       Test.userInformation.lastName
    };
    
    ItemToSend.authenticationProvider = new Test.itemProvider[] 
    {
       Test.itemProvider.authltidentitycard,
       Test.itemProvider.authltbank,
       Test.itemProvider.authsignatureProvider,
       Test.itemProvider.authltgovernmentemployeecard
    };
    
    ItemToSend.authenticationAttribute = new Test.itemAttribute[]
    {
       Test.itemAttribute.ltpersonalcode,
       Test.itemAttribute.ltcompanycode
    };
    

    用于在将SOAP消息发送到Web服务之前修改SOAP消息的代码:

    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
    {
       XmlDocument doc = new XmlDocument();
       MemoryStream ms = new MemoryStream();
       XmlWriter writer = XmlWriter.Create(ms);
       request.WriteMessage(writer);
       writer.Flush();
       ms.Position = 0;
       doc.Load(ms);
       SignDocument(doc, System.Web.HttpContext.Current.Server.MapPath("~/App_LocalResources/testCert.pem"), System.Web.HttpContext.Current.Server.MapPath("~/App_LocalResources/testKey.pem"));
       //ChangeMessage(doc, true);
       ms.SetLength(0);
       writer = XmlWriter.Create(ms);
       doc.WriteTo(writer);
       writer.Flush();
       ms.Position = 0;
       XmlReader reader = XmlReader.Create(ms);
       request = Message.CreateMessage(reader, int.MaxValue, request.Version);
       return null;
    }
    

    要放入SOAP消息的签名XML(doc对象的内容):

    <?xml version="1.0" encoding="utf-8"?>
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
      <s:Header>
        <Action xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none" s:mustUnderstand="1">http://www.epaslaugos.lt/services/authenticationServiceProvider/initAuthentication</Action>
      </s:Header>
      <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <authenticationRequest xmlns="does not matter">
          <pid>VSID000000000113</pid>
          <serviceTarget>citizen</serviceTarget>
          <authenticationProvider>auth.lt.identity.card</authenticationProvider>
          <authenticationProvider>auth.lt.bank</authenticationProvider>
          <authenticationProvider>auth.signatureProvider</authenticationProvider>
          <authenticationProvider>auth.lt.government.employee.card</authenticationProvider>
          <authenticationAttribute>lt-personal-code</authenticationAttribute>
          <authenticationAttribute>lt-company-code</authenticationAttribute>
          <userInformation>id</userInformation>
          <userInformation>firstName</userInformation>
          <userInformation>lastName</userInformation>
          <postbackUrl>does not matter</postbackUrl>
          <customData>correlationData</customData>
          <id>uniqueNodeId</id>
        </authenticationRequest>
      </s:Body>
      <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
          <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
            <InclusiveNamespaces xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="s"/>
          </CanonicalizationMethod>
          <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
          <Reference URI="">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <InclusiveNamespaces xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="s"/>
              </Transform>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>vXs8k7faSipYtQ7AGsbP2yK0Nxo=</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>aPdWNziCci0F5/Qt+naKWqBjV9XVHyjk5YEX0tDXBOx4tbrh26bwl8DJuMULZ7RIXzxUQ8SD94T+Qsd1H83u7xCt8c1iWyMSJv0hSp2RIj3V+VyqnpkHJMIbZghUtRb11R7PeJTJEUtlS42PNRhCILtsfn7G65YCDtsNKhCL/8hqcJyg4/kBx9OFzJTga+1mXgIYusN8vlQdMog0CISNOxYn8MwG/XOlPbybyv3CjT2eethPZ6dFo8FE1qFkYq8txiSjxSaVlhxRedcWtiAf5r7LvXWvnYP85mZ86A3BHPT2/jq9hHtnNPzgvKJ3QrtHuY0lE5AuTnPIZBNKjkUnVQ==</SignatureValue>
        <KeyInfo>
          <KeyValue>
            <RSAKeyValue>
              <Modulus>i+rh6NJ7Z6Q8XiMSVK/Z8DYXIyk5j7N9GUX8AOSKONabse4us7/ogR0x7OOf0FsrdxAhQls59Wn1vDxujSVOu3v1JhML/v/WK8glcxM433oEEpb0C56XRHlt27Qkbsn6v3njC1z0NGyDFdAtg5PaMx7YmjyWR6ezMKj9wR5cK4CRZ7idm2PwzQaLUDFm7wUFXudZNkQ6pb60OvDw4ey1t68EVCPtq4nGdHG+3jlSDTTJc/03qk50pa6Nb/t5+EWsE3jFt/uhHim1rC2pMf5UrT26FL6/DjA0PxQFecc76zeuv3xbGSP7B7ubpG8fyatGb4oLB4eU0ceCJvqljGMP0w==</Modulus>
              <Exponent>AQAB</Exponent>
            </RSAKeyValue>
          </KeyValue>
        </KeyInfo>
      </Signature>
    </s:Envelope>
    

    这个问题最有趣的部分是Message.CreateMessage()方法运行正常。生成请求对象,但是在将消息发送到Web服务之前抛出异常。

    感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

所以问题是我试图签署整个SOAP消息,而不是XML本身。签署XML解决了这个问题。