My team is designing a RESTful API in JAX-RS, and we have the need to restrict the availability of certain rows in our database based on the ID of the authenticated "Operator" (our word for User). In other words, an Operator should only be able to access entities that are under his jurisdiction. At the beginning of each request, we authenticate the Operator making the request, allowing us to provide security features based on the Operator's role and ID.
Authorizing endpoints, endpoint methods and even entity content (what gets serialized) has proven fairly straightforward, but row-level authorization seems to be a big hairy beast.
Note that we are not using Spring, and have no plans to use Spring Security in our project.
We've come up with a few potential solutions, but we're unsure which is best. It's also very possible that there's a solution we haven't considered; I'm open to anything at this point. Here's what we've got so far:
- Database level implementation (as discussed in this post). This would presumably involve using the request's security context to pass the Operator's ID to the database on each request. I'm unclear on the specifics of implementing this approach, so if this is the best way to do row-level security I'd appreciate some further advice. For example, it makes sense how this would work for entity retrieval, but how would we modify row-level permissions for newly created or updated entities?
- JPA level implementation (as discussed in this post from 2008). This might involve generating a parameterized Hibernate filter into which we'd feed the ID of the Operator making the request. I've never used Hibernate filters so it's very possible that this idea is off-base.
- Facade level implementation. We've actually given this idea a decent amount of thought since we weren't aware of options (1) and (2) until recently. This would involve performing joins between our tables to construct a Criteria API predicate that would restrict our queries to only include those entities accessible by a given Operator. This is essentially the "manual" approach, as far as I understand it, and seems far from ideal.
It would be awesome if someone familiar with JAX-RS and/or database security could help make some sense of all of this.
Here's our tech stack for the project (at least as far as is relevant to this problem):
- Database: MS SQL
- JPA Provider: Hibernate
- JAX-RS Implementation: RESTEasy