Reputation: 1971
I have avoided using
and have not closed the Stream
after reading several posts in StackOverflow but still keep getting the error:
Cannot access a closed Stream.
Here is my asp.net core
middleware I wrote to decrypt the incoming payload and override the HttpContext.Request.Body
with the decrypted string.
public class DecryptMiddleware
{
private readonly RequestDelegate _next;
private X509Certificate2 cert;
public DecryptMiddleware(RequestDelegate next)
{
cert = new X509Certificate2(@"C:\Program Files\OpenSSL-Win64\bin\SandBox\07122020\my-cert.pfx", "xxxxxxxx");
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
//body => stream
var encryptedRequestData = httpContext.Request.Body;
var encryptedAttributeData = string.Empty;
var decryptedResponseData = String.Empty;
if (httpContext.Request.Method == "POST")
{
//DeSerialize
var encryptedData = string.Empty;
StreamReader stream = null;
try
{
stream = new StreamReader(encryptedRequestData);
var body = await stream.ReadToEndAsync();
var request = JsonConvert.DeserializeObject<SecureTestClass>(body);
encryptedData = request.JData;
}
finally
{
if (stream != null) //I tried avoiding this code but still keep getting the error
{
stream.Close();
stream.Dispose();
}
}
//Decrypt
var rsa = (RSACng)cert.PrivateKey;
decryptedResponseData = Encoding.UTF8.GetString(
rsa.Decrypt(Convert.FromBase64String(encryptedData)
, RSAEncryptionPadding.Pkcs1)
);
httpContext.Request.Body = GenerateStreamFromString(decryptedResponseData);
}
await _next(httpContext);
await httpContext.Request.Body.DisposeAsync();
}
public static Stream GenerateStreamFromString(string s)
{
StreamWriter sw = null;
StreamReader sr = null;
MemoryStream ms = null;
try
{
ms = new MemoryStream();
sw = new StreamWriter(ms);
sr = new StreamReader(ms);
sw.WriteLine(s);
ms.Position = 0;
}
finally
{
if (sw != null) sw.Dispose();
if (sr != null) sr.Dispose();
}
return ms;
}
}
And the Error I am getting is:
{
"Message": "Cannot access a closed Stream.",
"Exception": "System.ObjectDisposedException: Cannot access a closed Stream.\r\n at System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.IO.MemoryStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Text.Json.JsonSerializer.ReadAsync[TValue](Stream utf8Json, Type returnType, JsonSerializerOptions options, CancellationToken cancellationToken)\r\n at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)\r\n at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)\r\n at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)\r\n at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value)\r\n at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)\r\n at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)\r\n at BankServiceListener.Middleware.DecryptMiddleware.InvokeAsync(HttpContext httpContext) in C:\\Projects\\GIT\\JKSB\\BankServiceListener\\BankServiceListener\\Middleware\\DecryptionMiddleware.cs:line 69\r\n at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\r\n at BankServiceListener.Middleware.DeveloperExceptionMiddleware.InvokeAsync(HttpContext httpContext) in C:\\Projects\\GIT\\JKSB\\BankServiceListener\\BankServiceListener\\Middleware\\DeveloperExceptionMiddleware.cs:line 27",
"StackTrace": " at System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.IO.MemoryStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Text.Json.JsonSerializer.ReadAsync[TValue](Stream utf8Json, Type returnType, JsonSerializerOptions options, CancellationToken cancellationToken)\r\n at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)\r\n at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)\r\n at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)\r\n at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value)\r\n at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)\r\n at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)\r\n at BankServiceListener.Middleware.DecryptMiddleware.InvokeAsync(HttpContext httpContext) in C:\\Projects\\GIT\\JKSB\\BankServiceListener\\BankServiceListener\\Middleware\\DecryptionMiddleware.cs:line 69\r\n at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\r\n at BankServiceListener.Middleware.DeveloperExceptionMiddleware.InvokeAsync(HttpContext httpContext) in C:\\Projects\\GIT\\JKSB\\BankServiceListener\\BankServiceListener\\Middleware\\DeveloperExceptionMiddleware.cs:line 27",
"Source": "System.Private.CoreLib"
}
Am I doing something wrong here? Can't figure it out.
Upvotes: 2
Views: 4249
Reputation: 87
seems you are disposing the StreamWriter sw, which in turn will dispose the memory stream passed to it
try using this
public static Stream GenerateStreamFromString(string s)
{
var ms = new MemoryStream(Encoding.Default.GetBytes(s));
return ms;
}
Upvotes: 2