2009-10-16 6 views
1

ASP.NET 웹 서비스에서 SOAP 메시지를 노래하고 암호화하려고합니다. 나는 AfterDeserialize에서 SOAP 메시지를 로그인 할 때SOAP 확장 기능이있는 ASMX 웹 서비스 - 암호화 방법의 문제점

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."); 
      } 

     } 
    // ... 
} 

문제는 XML은 일반 텍스트이지만 누군가가 나를 도울 수 암호화해야합니다

//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; 
     } 
} 

나는 비누 확장 클래스에서 CryptUtility 객체를 사용 문제가 될 수있는 곳, 또는 무엇을 나쁘게 할 수 있습니까?

먼저 클래스 SoapMsg에서 EncryptAndSingXml 메서드를 void로 사용하기 때문에 올바로 작동합니다. 이런 식으로 뭔가 :

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

하지만 클래스 CryptUtility 및 방법의 EncryptAndSingXml을 makec 때() 가상로 작동하지 않습니다. :( 누군가는 CryptUtility의 인스턴스를 만들 위치를 보여주십시오! 당신이 모든 message을 수정처럼

답변

1

그것은 보이지 않는?

을 도와 수 있습니다.

을 또한, 코드를 아주 나쁜이을 시도해보십시오.

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."); 
     } 

    } 
    // ... 
} 
+0

초기화시 CryptUtility를 만듭니다. advanace 주셔서 감사합니다, 그것은 작동합니다. 사용하는 이유는 무엇입니까? 예 : using (XmlReader reader = XmlReader.Create (inputStream)) { doc.Load (reader); } ASP.NET을 사용하는 데 한 달 밖에 걸리지 않습니다. –

+0

'using'은'IDisposable'을 구현하는 타입의 인스턴스를 생성 할 때 사용됩니다. 예외가 발생하더라도'IDisposable.Dispose'가 호출되도록합니다. 규칙은 - 당신이 그런 타입의 인스턴스를 생성한다면, 그것을'using' 블록으로 감싸 야합니다. –

+0

진보 감사합니다. 지금 instace가 iterface IDisposable을 구현한다면 지금 사용하여 인스턴스를 생성 할 것입니다. –