Open SphtKr opened 9 years ago
Ah yes, authorization. I haven't tackled this on my project yet, but my requirements are something as follows:
I intend to do authorization stuff in general in my service layer. Currently I have my own base ApiController that exposes Get(), Put(), et al., which merely wrap service layer methods. In order for me to be able to use ApiController<>, I need to be able to maintain this separation of concerns (i.e., IMaterializer has to be able to do everything).
So I don't know how much authorization needs to be done in this library. At least as far as my project goes, the service layer has to be able to tell the API which fields NOT to serialize on a per-request basis, and when to return a 403 entirely.
(BTW, I know the service layer could just return null for fields the user can't read. But I need some way to communicate to the client app the difference between a field that has been restricted and one that just has null data. In the latter case the client will render an empty field; in the former, the field is completely hidden.)
So I don't know how much authorization needs to be done in this library.
Right, I'm more getting at providing hooks where the user can specify their own authorization logic. Particularly because it would be handy within, for instance, EntityFrameworkMaterializer.Merge
to catch attempted changes to properties while such changes were being made. Wherever #36 goes, similar hooks in Post
and Delete
methods would be handy too.
If a user only has access to some of the fields on a resource, they should only see the fields they have read-access to. ... the service layer has to be able to tell the API which fields NOT to serialize ... I need some way to communicate to the client app the difference between a field that has been restricted and one that just has null data. In the latter case the client will render an empty field; in the former, the field is completely hidden.
I'm concerned that if we build this behavior into the library that we'll butt up against support for sparse fieldsets, which is a cool way to save bandwidth and I'd like to support it. Personally I'd recommend finding another way to communicate to your client that the field was restricted (meta
key in the payload? once upon a time I thought the spec had provisions for the meta
key within a resource). Nevertheless, you might look into building a IContractResolver
for your model objects, which I hope
can be used on top of JSONAPI.NET.
This is something I had attempted the oft-mentioned original version of this library, but it ended up very very cumbersome and error prone--I'm not sure this will be practical
The "Dream" of
JSONAPI.EntityFramework.Http.ApiController
and really ofJSONAPI.Http.ApiController
andIMaterializer
is to be able to provide an almost completely canned JSON API compliant service broker--all you have to do is to override/implement a few interface points to integrate with your persistence layer and you're done. However, especially in the case of the EFApiController
, this has turned out to be more pipe dream so far, as I usually have to override the verb methods and it's hard to reuse the super-method.One of the main reasons I find myself having to throw away the default verb implementations (particularly
Put
,Post
, andDelete
is to insert authorization controls, for example to make sure users can only edit their own records. Additionally, I often need to control things at the property level, e.g. a user can't change theOwner
of a record to someone else (but an admin user may be able to do this).In the current architecture, the separation of the deserialization from the
IMaterializer
provides a good place to inject a reusable authorization layer. We could add anIAuthorizationProvider
property to theIMaterializer
, and have some API for theIMaterializer
to ask theIAuthorizationProvider
whether any given property update should be allowed. This in theory would be good from a separation of concerns perspective, because it would encourage encapsulation of security logic from other business logic.Gotchas (from previous experience):
Order Deny,Allow; Deny from All
). This sounded good, but led to the definition of more exceptions than rules--possibly not the best way to go.