Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change request body in IActionFilter in asp.net core

Currently I am sending encrypted request to asp.net core controller. The following is the request body structure:

{
  "body": "pEbXVvl1ue95eGQywK/q80cGHjYk+2VNPYEgnRgU+vI="
}

Before that I had implemented the filter IActionFilter so in OnActionExecuting(ActionExecutingContext context) where I decrypt the above mention request body(body key)

After decryption, I got the decrypted request body like below:

{
  "Urno":"URN123456"
}

After decryption, I want to pass decrypted request (mentioned above "Urno":"URN123456") body to controller

I had tried to convert the string to byte than pass it to Request.body but no success:

public void OnActionExecuting(ActionExecutingContext context)
{
    var request = context.HttpContext.Request;
    request.EnableRewind();
    request.Body.Position = 0;
    using (var reader = new StreamReader(request.Body))
    {                   
        var bodyString = reader.ReadToEnd(); //{ "body": "pEbXVvl1ue95eGQywK/q80cGHjYk+2VNPYEgnRgU+vI="}
        if (bodyString != "")
        {
             var data = JObject.Parse(bodyString);
             var key = data.GetValue("body"); 
             var keybytes = Encoding.UTF8.GetBytes("808080808080808011");
             var iv = Encoding.UTF8.GetBytes("8080808080808080111");
             var encrypted = Convert.FromBase64String(key.ToString());
             var decriptedFromJavascript = DecryptStringFromBytes(encrypted, keybytes, iv); //{ "Urno":"URN123456"}
             byte[] bytes = Encoding.ASCII.GetBytes(decriptedFromJavascript);
             request.Body = new MemoryStream(bytes); // here i am trying to change request body
        }
    }
}
   // controller
[HttpPost("[action]")]
public async Task<string> GetInvestorUrno(Urnoinvestor InfoReq){

}


// class
public class Urnoinvestor 
{
    public string Urno{ get; set; }
}

I want to change request body and pass the decrypted request to controller

like image 439
Khon Avatar asked Mar 04 '23 23:03

Khon


1 Answers

For your scenario, IActionFilter would not work. Check this image:

enter image description here

The Model binding is run before ActionFilter which means no matter what you changed to the body, it would not change the model. You need to try the filter before Model binding like Resource filter.

  1. Change to Resource filter

    public class RequestBodyFilter : IResourceFilter
    {
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            //throw new NotImplementedException();
        }
    
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            var request = context.HttpContext.Request;
            request.EnableRewind();
            request.Body.Position = 0;
            using (var reader = new StreamReader(request.Body))
            {
                var decriptedFromJavascript = "{ \"Urno\":\"URN123456\"}"; //{ "Urno":"URN123456"}
                byte[] bytes = Encoding.ASCII.GetBytes(decriptedFromJavascript);
                request.Body = new MemoryStream(bytes); // here i am trying to change request body
            }
        }
    }
    
  2. Since you are binding from body, you need to specify the action with [FromBody] as the suggestion from @Tony Abrams.

    [HttpPost("[action]")]
    [TypeFilter(typeof(RequestBodyFilter))]
    public async Task<string> GetInvestorUrno([FromBody]Urnoinvestor InfoReq)
    {
        return InfoReq.Urno;
    }
    
like image 75
Edward Avatar answered Mar 19 '23 12:03

Edward