1

ASP.NET Web サービスで SOAP メッセージを歌って暗号化してみます。

//I have Crypt class, which input parameters is Stream:
public class CryptUtility
 {
      public virtual Stream EncryptAndSingXml (Stream inputStream)
      {
         XmlTextReader reader = new XmlTextReader(inputStream);
         XmlDocument doc = new XmlDocument();
         doc.Load(reader);

         // in this place I encrypt and sign SOAP message
         foreach (string xPathQuery in soapElement)
          {
          XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
            foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
              {
                // method EncryptString crypt only string from XmlNode
                nodeToEncrypt.InnerXml = EncryptString();
              }
           }

         // !!!
         //               I        THINK  HERE IS A PROBLEM 
         //
         //it return plain stream, no encrypt stream
         MemoryStream retStream = new MemoryStream();
         XmlTextWriter writer = new XmlTextWriter(retStream, Encoding.UTF8);
         doc.Save(retStream);
         return retStream;
      }
 }

Soap 拡張クラスで CryptUtility オブジェクトを使用しました。

public class SoapMsg : SoapExtension
 {
     private CryptUtility cryptUtil; //this object crypt and sing SOAP message
     //  ...

     //this method copy stream
     private void CopyStream(Stream from, Stream to)
     {
     TextReader reader = new StreamReader(from);
     TextWriter writer = new StreamWriter(to);
     writer.Write(reader.ReadToEnd());
     writer.Flush();
     }

     //this method sing and encrypt SOAP message, I call this method in stage  AfterSerialize
     private void CryptMessage()
     {
     newStream.Position = 0;
     Stream retStream = cryptUtil.EncryptAndSingXml(newStream);
     retStream.Position = 0;
     CopyStream(retStream, oldStream);
     }

     public override void ProcessMessage(SoapMessage message)
     {
       switch (message.Stage)
         {
           case SoapMessageStage.BeforeSerialize:
              break;
           case SoapMessageStage.AfterSerialize:
           {
           // call the crypt and sing method
           CryptMessage();
           //save the SOAP message, the message is not encrypt
           Log(message, "AfterSerialize");
           }
             break;
           case SoapMessageStage.BeforeDeserialize:
              break;
           case SoapMessageStage.AfterDeserialize:
               break;
            default:
              throw new ArgumentException("error.");
           }

        }
     // ...
 }

問題は、AfterDeserialize で SOAP メッセージをログに記録すると、XML はプレーン テキストですが、暗号化する必要があります。

最初にメソッド EncryptAndSingXml をクラス SoapMsg の void として使用し、正しく動作するためです!!! このようなもの :

 public class SoapMsg : SoapExtension
 {
 //...
      public void EncryptAndSingXml()
      {...}
 //...
     public override void ProcessMessage(SoapMessage message)
     {
       switch (message.Stage)
         {
           //...
           case SoapMessageStage.AfterSerialize:
           EncryptAndSingXml();
               break;
           //...
        }
     // ...
 }

しかし、クラス CryptUtility とメソッド EncryptAndSingXml() を仮想として作成すると、機能しません。:( 誰かが私を助けることができますか?

4

1 に答える 1

1

あなたがまったく変更しているようには見えませんmessage

そして、 のインスタンスを作成する場所を示してくださいCryptUtility

また、あなたのコードはかなり悪いです。これを試して:

public class CryptUtility
{
    public virtual Stream EncryptAndSingXml(Stream inputStream, IEnumerable<string> soapElement)
    {
        XmlDocument doc = new XmlDocument();
        using (XmlReader reader = XmlReader.Create(inputStream))
        {
            doc.Load(reader);
        }

        // in this place I encrypt and sign SOAP message
        XmlNamespaceManager nsMan = new XmlNamespaceManager(doc.NameTable);
        foreach (string xPathQuery in soapElement)
        {
            XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
            foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
            {
                // method EncryptString crypt only string from XmlNode
                nodeToEncrypt.InnerXml = EncryptString(nodeToEncrypt.InnerXml);
            }
        }

        // !!!
        //               I        THINK  HERE IS A PROBLEM 
        //
        //it return plain stream, no encrypt stream
        using (MemoryStream retStream = new MemoryStream())
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = Encoding.UTF8;
            using (XmlWriter writer = XmlWriter.Create(retStream, settings))
            {
                doc.WriteTo(writer);
            }
            return retStream;
        }
    }
}

public class SoapMsg : SoapExtension
{
    private CryptUtility cryptUtil; //this object crypt and sing SOAP message
    //  ...

    //this method copy stream
    private void CopyStream(Stream from, Stream to)
    {
        using (TextReader reader = new StreamReader(from))
        {
            using (TextWriter writer = new StreamWriter(to))
            {
                writer.Write(reader.ReadToEnd());
                writer.Flush();
            }
        }
    }

    //this method sing and encrypt SOAP message, I call this method in stage  AfterSerialize
    private void CryptMessage()
    {
        newStream.Position = 0;
        using (Stream retStream = cryptUtil.EncryptAndSingXml(newStream))
        {
            retStream.Position = 0;
            CopyStream(retStream, oldStream);
        }
    }

    public override void ProcessMessage(SoapMessage message)
    {
        switch (message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                {
                    // call the crypt and sing method
                    CryptMessage();
                    //save the SOAP message, the message is not encrypt
                    Log(message, "AfterSerialize");
                }
                break;
            case SoapMessageStage.BeforeDeserialize:
                break;
            case SoapMessageStage.AfterDeserialize:
                break;
            default:
                throw new ArgumentException("error.");
        }

    }
    // ...
}
于 2009-10-17T03:33:14.187 に答える