-
Notifications
You must be signed in to change notification settings - Fork 562
Add ability to only expose repository methods explicitly declared for exposure [DATAREST-1176] #1510
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
Comments
Oliver Drotbohm commented If you want to be so very selective about the exposed functionality, why not write a single controller method that just calls that very method? I am not sure we should broaden the semantics of |
Tobias Weiss commented We had the same idea of adding an attribute to |
Oliver Drotbohm commented That looks interesting. There's a couple of things I don't quite like about the approach (again: bending the repository detection strategy to now include which methods to expose by default). However, it looks nice enough to try to tweak it and see where this could go. Do you think you could submit that commit as pull request against Spring Data REST so that I could play with it a little? |
Tobias Weiss commented I've created the pull request #286 |
Oliver Drotbohm commented I gave this a quick spin and you can find our combined changes here now. I basically expose the new criterion on I am still not quite sure about the naming of the enum, as that's where the mismatch of the concepts now becomes most clear. There's just no nice name to mention the additional method exposure defaulting. Yet another different option would be to introduce a flag on WDYT? |
Johannes Rudolph commented Let me jump in here and add a few thoughts. I'm on the same team as Tobi. We have an array of micro-services in production with SDR at meshcloud.io While we found SDR was great for getting an API up and running quickly, we had some issues scaling it to services with more domain complexity than plain CRUD. With SDRs defaults, we repeatedly found that it was too easy to leave a Repository method "exported" (especially inherited save/findAll/delete methods) or accidentlly expose a "priviledged" method that executes a query across tenants in our database. We chose the latter option as we do have som plain CRUD that we want to leverage SDR for and we found it painful to wrap SDR manually in a controller while retaining its full capabilities (projections, search, paging etc.). Re. naming: maybe the RepositoryDetectionStrategy should also have a companion "MethodDetectionStrategy" instead? This would split responsibility for finding the right repositories (i.e. based on package, annotations etc.) and then selecting the appropriate methods from the repositories? |
Miguel Pereira commented This would be a great feature. I'd also prefer if the there existed a detection strategy exported no methods by default unless annotated. Also related. From a multi module approach I've used the default repository detection strategy in Module A and annotated in Module B which depends on module A. This allows me to re-use the repository / services defined in module A in module B without also exporting them. The issues arises when a new developer creates a repository and isn't aware that he/she should not annotate the interface or when we would like to use the annotation to customize the the excerpt projection, path, or when someone decides to make module C and doesn't have as much experience with SDR. As mentioned above in my use case we also needed more control over the basic operations (save/findOne/delete etc) for complex security / auditing requirements (some of which can be done in the event handlers). I ended up disabling exporting altogether and writing my own controllers that still use core SDR classes like Repositories, RepositoriesEntityLinks, PersistentEntityResourceAssembler... Copying some of the methods in AbstractRepositoryRestController and mimicing RepositoryEntityController since they are package private and I cannot extend them directly. Still not sure how to get access to RootResourceInformation :/ Also I couldn't figure out how to add discoverable links to the RepositorySearchController for repositories that where not exported so I ended up adding my own request handler for /search in my custom controller. I think id like to disable the RepositoryController, RepositorySearchController altogether. Sorry if I'm mixing issues / topics just wanted to describe how I'm attempting to use SDR. (which I like a lot :) |
Oliver Drotbohm commented I've just pushed a proper feature branch for this issue that already produced binaries for you to test. On the highest level you can now basically call It would be cool if you could give the snapshots a try (use version |
Tobias Weiss commented I reviewed your changes. The solution is exactly what I prefer. I think it is a very nice idea to configure the default exposure value on a central place and use the |
Oliver Drotbohm commented There's now a |
Tobias Weiss commented Thank you for the new snapshot. I tested our project with the new feature and it runs perfectly. All our endpoint behavior tests runs correctly. Very nice! |
Oliver Drotbohm commented Thanks for the quick feedback. I'll go ahed and merge the changes then. And then update the docs… 😬 |
Oliver Drotbohm commented That's merged, backported and available in the canonical snapshot binaries now. Ingalls SR10 coming next week |
Tobias Weiss commented Awesome :) Thanks a lot to integrate our feature so quickly! |
Oliver Drotbohm commented You're most welcome. Feedback always appreciated |
Tobias Weiss opened DATAREST-1176 and commented
The currently available detection strategies in SDR only allow to restrict REST repositories on class level. So when a Repository is exported, all of its methods are exported, too. Only by using
RestResource(exported = false)
, you can prevent SDR from exporting a given method.We identified in our project, that there is a certain security risk in that case. Developers are not always aware of all the methods that are automatically exported via REST by the application. By simply adding new Repositories and just wanting a
findAll()
-method to be publicly available, even save and delete methods are exported by default. As most applications want to apply security especially on the write methods, an additional "pessimistic" strategy can be useful in Spring. That way you can still profit from all the benefits SDR provides, but you can be sure, that only methods you explicitly added and annotated with@RestResource
are exported.The following example shows how the exporting with the new strategy should work:
In that case, only the
findAll()
method is exported via REST. The findByFirstName and all CRUD methods like save or delete are not exported via REST by default. They have to be added explictily and annotated with@RestResource
if they shall be exported via RESTIssue Links:
("is duplicated by")
Backported to: 3.0.3 (Kay SR3), 2.6.10 (Ingalls SR10)
1 votes, 5 watchers
The text was updated successfully, but these errors were encountered: