There are a lot of questions on here that deal with the mechanics of authentication and authorization of RESTful APIs but none of them appear to go in to details of how to implement secure services at the application level.
For example let's say that my webapp (I've got Java in mind but this applies to any backend really) has a secure authentication system that allows users of the API to login with a username and password. When the user makes a request, at any point during the request processing pipeline I can call a getAuthenticatedUser()
method which will return either the null user if the user isn't logged in, or a User domain object that represents the logged in user.
The API allows authenticated users to access their data e.g. a GET to /api/orders/
will return that user's list of orders. Similarly, a GET to /api/tasks/{task_id}
will return data relating to that specific task.
Let's assume that there are a number of different domain objects that can be associated with a user's account (orders and tasks are two examples, we could also have customers, invoices etc.). We only want authenticated users to be able to access data about their own objects so when a user makes a call to /api/invoices/{invoice_id}
we need to check that the user is authorized to access that resource before we serve it up.
My question is then, do patterns or strategies exist to deal with this authorization problem? One option I'm considering is creating a helper interface (i.e. SecurityUtils.isUserAuthorized(user, object)
), which can be called during request processing to ensure that the user is authorized to fetch the object. This isn't ideal as it pollutes the application endpoint code with lots of these calls e.g.
Object someEndpoint(int objectId) {
if (!SecurityUtils.isUserAuthorized(loggedInUser, objectDAO.get(objectId)) {
throw new UnauthorizedException();
}
...
}
...and then there's the question of implementing this method for every domain type which could be a bit of a pain. This might be the only option but I'd be interested to hear your suggestions!