I call method in Soap extension which decrypt and verify sing Soap message. I have this classes:
I have class, which decrypt and verify sign Soap message, which return stream back in Soap extension class :
Method DecryptAndVerifySingXml and GetGuid use stream from class soap extension.
public class CryptUtility
{
public virtual Stream DecryptAndVerifySingXml(Stream inputStream)
{
XmlDocument doc = new XmlDocument();
using (XmlTextReader reader = new XmlTextReader(inputStream))
{
doc.Load(reader);
}
using (MemoryStream retStream = new MemoryStream())
{
retStream.Position = 0;
doc.Save(retStream);
}
//.....crypt and verify sing
if (signedXml.CheckSignature(Key) == false)
{
throw new SecurityException("error");
}
else
{
using (MemoryStream retStream = new MemoryStream())
{
doc.Save(retStream);
return retStream;
}
}
}
//get value from Soap header
public string GetGuid(MemoryStream inputStream)
{
inputStream.Position = 0;
string soapBodyString = Encoding.UTF8.GetString(inputStream.ToArray());
XmlDocument doc = new XmlDocument();
doc.LoadXml(soapBodyString);
if (doc.GetElementsByTagName("Ticket").Item(0).InnerText == "")
{
throw new SecurityException("Neplatny uzivatel");
}
else
{
return doc.GetElementsByTagName("Ticket").Item(0).InnerText;
}
}
}
I use class CryptUtility in Soap extension class:
public class SoapMsg : SoapExtension
{
private CryptUtility cryptUtil = null;
string GUID;
//...
public override void Initialize(object initializer)
{
SoapMsgAttribute attribute =
initializer as SoapMsgAttribute;
soapElement = attribute.SoapElementArray;
//create instance
cryptUtil = new CryptUtility();
}
//copy stream method
private void CopyStream(Stream from, Stream to)
{
TextReader reader = new StreamReader(from);
TextWriter writer = new StreamWriter(to);
writer.Write(reader.ReadToEnd());
writer.Flush();
}
private void DecryptMessage()
{
using (MemoryStream copyOldStream = new MemoryStream())
{
CopyStream(oldStream, copyOldStream);
copyOldStream.Position = 0;
using (Stream retStream = cryptUtil.DecryptAndVerifySingXml(copyOldStream)
{
retStream.Position = 0; // < == in this place is bug !!! line 183.
newStream.Position = 0;
CopyStream(retStream, newStream);
newStream.Position = 0;
}
}
}
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
{
}
break;
case SoapMessageStage.BeforeDeserialize:
{
using (MemoryStream tempStream = new MemoryStream())
{
CopyStream(oldStream, tempStream);
tempStream.Position = 0;
GUID = cryptUtil.GetGuid(tempStream);
oldStream.Position = 0;
// call method, in which is bug
DecryptMessage();
}
break;
case SoapMessageStage.AfterDeserialize:
break;
default:
throw new ArgumentException("error");
}
}
}
}
In ProcessMessage in BeforeDeserialize I call method DecryptMessage() in wich is bug. On client side Sopa extension finish with this error :
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.ObjectDisposedException: Cannot access a closed Stream. at System.IO.__Error.StreamIsClosed()
The error is in line : retStream.Position = 0; // < == in this place is bug !!! line 183. in method DecryptMessage().
First I used google, but I don't find solution for this error. Can somebody help me ?