3

For my OData based Web API, I have an additional layer of authentication which checks if the user has the proper rights to access a model. Now, when $expand is used in the query, the binding of models completely bypasses these authorization checks.

What I want, is when calling (for example) /odata/Countries(2)?$expand=Locations,People, and the authorization layer reports that the current user has no rights to retrieve People, a response is still given, but only with Locations bound to Countries. So the not-accessible People model should not be returned alongside Countries.

I could derive from SelectExpandQueryValidator and modify the Validate function. But this only allows me to declare an expand query invalid, not to modify it. Even more so, this is an authentication issue, and does not belong in validation. Also, I need the Countries entity in order for the authentication layer to determine whether Locations or People may be accessed.

Subsequently, I took a look at the System.Web.Http.OData.Query namespace, and found that I should somehow modify the RawExpand property SelectExpandQueryOption. But since this is read-only (and also really seems like hacking), I started to look for alternatives. Only, I cannot find when the ODataQueryOptions class is called in order to use the ApplyTo methods (which in my case binds all expand models). So it comes down to this: how can I modify the way $expand binds models, whilst I'm already inside the method that is called?

Since this is a really specific $expand question, of beta functionality nonetheless, I'm probably looking at the ASP.NET Web API developers who are lingering around here. Am I missing some obvious functionality here, or are my demands too high? Thanks in advance!

Kazu
  • 627
  • 6
  • 17
  • Hi, did you ever determine a good way to do this? I'm trying to accomplish the same thing right now. – pharophy Nov 04 '15 at 01:27
  • Unfortunately, I did not. The project for which I was developing this was scrapped shortly before the first RTM of WebAPI was released, so I never got the chance to see if this was resolved later on. Should anyone ever get to the point where he/she can solve this in the newest WebAPI releases, I would still like to know how this can be resolved. – Kazu Nov 04 '15 at 15:40

2 Answers2

2

I know this question is kind of old, however as I was stumbling over the same issue where I still had to deal with ODATAv3 and I thought I might still comment on this.

We basically have to options to modify ODataQueryOptions:

Replacing ODataQueryOptions inside the respective Controller method

Here we can replace the query options by creating new ones and updating the reference inside the method.

Replacing ODataQueryOptions inside HttpActionContext.ActionArguments via subclassed EnaleQuery attribute

With this option we replace the query options inside the ActionContext by defining a custom [EnableQueryAttribute].

The actual implementation is a three step approach:

  1. We first analyise and parse the RequestUri inside the ODataQueryOptions and throw out options we do not need or want to alter.
  2. Then we can create a new RequestUri from that and replace the original RequestUri in the HttpRequestMessage ...
  3. ... and in the last step we create new ODataQueryOptions associated with the original ODataQueryContext and just changed HttpRequestMessage.

Both ways are described in more detail with actual code examples in Modifying ODataQueryOptions on the fly.

Hope it helps. Regards, Ronald

Ronald Rink 'd-fens'
  • 1,289
  • 1
  • 10
  • 27
0

have you try to use WebApi V4? there is a question about modify the filter, I think you can do this for SelectExpand too. OData V4 modify $filter on server side

Community
  • 1
  • 1
Fan Ouyang
  • 2,132
  • 1
  • 11
  • 13