Skip to content

Question on authorization #1001

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bart-degreed opened this issue May 19, 2021 · 4 comments
Closed

Question on authorization #1001

bart-degreed opened this issue May 19, 2021 · 4 comments
Labels

Comments

@bart-degreed
Copy link
Contributor

See #977 (comment)

@bart-degreed
Copy link
Contributor Author

bart-degreed commented May 19, 2021

Question: At last, the question. Using resource definitions with write callbacks, is it possible to avoid having to implement two mechanisms, i.e., the First Mechanism that is based on FilterExpressions (also a new trick to learn for almost everybody) and the Second Mechanism that is based on Linq expressions?

I would say the answer is no. For the first mechanism, you're checking permissions on resource instances. This affects data going through the layers of the JADNC pipeline, thus requires FilterExpressions to avoid tight coupling with EF Core. OnApplyFilter is the best place to handle that. For the second mechanism, you're trying to answer a yes/no question on whether the operation is allowed based on resource type. It is not data that flows through the API, so you can answer that question by looking at live data (using LINQ expressions) or evaluate against a locally cached permission set. Doing that from controller actions sounds like a good approach to me.

Depending on security requirements, you may not want to differentiate between 'not found' and 'exists, but access denied'. But I'm assuming you do want to differentiate. So to implement 2:403, you can catch ResourceNotFoundException, then re-query without auth filter to see if the item does exist. If so, produce 403 error instead.

We intentionally provide no way to remove resources from the to-be-returned set afterwards, because it promotes bad design that does not scale. Its better to filter out what is unneeded using a WHERE clause, over fetching too much, then filtering in-memory. Another problem is paging: when filtering out elements before returning them, the paging is no longer correct: current page number and total number of pages is wrong and a non-last page contains less elements than the page size.

@maurei maurei mentioned this issue May 19, 2021
@ThomasBarnekow
Copy link

ThomasBarnekow commented May 19, 2021

@bart-degreed, thanks for the quick answer. There might be a misunderstanding regarding the second mechanism (using Linq expressions to check write access permissions). For example, consider a system that has Engagement (think procurement process or M&A transaction) and EngagementParty (think "bidder") resources. A user might have permission to read or write specific Engagement or EngagementParty instances. Users associated with a specific EngagementParty, for example, might only have the permission to read or edit their own EngagementParty but no other EngagementParty related to the Engagement (e.g., for reasons of confidentiality). Thus, this is not based on the resource types but also instances.

Regarding the differentiation in the case of read access, I currently return 403 Forbidden if the user does not have permission to access any EngagementParty instance, for example. I never return 404 Not Found.

I understand your point on "removing resources from the to-be-returned set afterward." So it has to be two mechanisms.

Now, from your point of view, would it be better to add the write access control part to the resource definition as well once you've added the write callbacks? Or should this remain in the controller?

If your recommendation were to add this to the resource definition, what would be the best way to deny write (post, patch, delete) access? Throw a JsonApiException with an appropriate Error?

P.S.: By the way, I have spent some time in The Hague and also Rijswijk.

@ThomasBarnekow
Copy link

@bart-degreed, you should change the title of the issue into "Question on authorization" or "Question on access control". It is not related to authentication, which happens before.

@bart-degreed bart-degreed changed the title Question on authentication Question on authorization May 19, 2021
@bart-degreed
Copy link
Contributor Author

bart-degreed commented May 19, 2021

If your recommendation were to add this to the resource definition, what would be the best way to deny write (post, patch, delete) access? Throw a JsonApiException with an appropriate Error?

Probably and yes. Probably because a controller executes earlier, so you can bail out quickly. If you're doing data access anyway to assert access, this advantage does not make much difference.

The engagement/party scenario you're describing sounds similar to multi-tenancy, we have an example for that, in case it helps. Its all in the details, I don't think there is a right way. Just experiment and see what happens, I think you're on the right track.

I studied at Rijswijk, but the institution was later merged with The Hague.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants