1

I have a similar question as enter link description here: if I want to update an object (sent in the body of a PUT) which contains an id, how can I obtain this id in the middleware without sending this Id in the route data?

Example: Given the object:

myObject= new MyObject
{
   id = 1,
   string "blah blah blah"
}

a user who has update rights on MyObject with id = 3 and who has NO UPDATE RIGHTS on MyObject with id = 1 uses Postman to send a PUT with the route /api/values/3 and the body myObject. The authorization middleware will be fooled with the id = 3 and will let the user modify the wrong object.

Of course I could add in the updateMethod a check (if (myObjectId != myObject.id) ...) or I could remove the id from the MyObject, but both solutions seem too much effort for such an edge case. The most straightforward way would be to be able to validate the actual data in the middleware.

Any way to do it? Is there a better approach I have not considered? thanks!

xavier
  • 1,860
  • 4
  • 18
  • 46

1 Answers1

1

I want to update an object (sent in the body of a PUT) which contains an id, how can I obtain this id in the middleware without sending this Id in the route data?

Achieve the above requirement in middleware/authorization filter, reading the posting data MyObject from request body is easy, but it does not support us write the modified MyObject data back to request body.

If possible, you can try to achieve it in action filter, like below.

public void OnActionExecuting(ActionExecutingContext context)
{
    if (context.HttpContext.Request.Path.StartsWithSegments(new Microsoft.AspNetCore.Http.PathString("/api/values")))
    {
        var user = context.HttpContext.User;

        //code logic here


        //check if request from client contains id in route data
        var routeData = context.HttpContext.Request.RouteValues;


        //update value of MyObject Id property based on your requirement 
        object myObject;

        if (context.ActionArguments.TryGetValue("myObject", out myObject))
        {
            MyObject _myobject = myObject as MyObject;

            _myobject.Id = 3;
        }
    }
}
Fei Han
  • 26,415
  • 1
  • 30
  • 41
  • Thanks for the answer! I don't need to modify the object. If the `id`s are different, I simply deny the authorization. I'd like to know, though, how to get the data in the middleware, since I'm trying to avoid using filters, as per https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#routing-startup-code (section Authorization and Authorization for specific endpoints, they recommend to move to refactor authorization filters into policies). – xavier Jan 17 '20 at 09:21