void4
void4

Reputation: 236

Authorization dependent REST API

as part of a server REST API design I'm considering I'd like to be able to return data that is conditional on the level of authorization of the client. What would be the recommended way of doing accomplishing that and still calling it one API? More specifically, consider the following example for a book access API:

HTTP GET /library/books/{book-name}
  1. Any authenticated client should be able to get (JSON) data for the book, like:

    { "book": {"book-name":"abc", "author":"someone"} }

  2. But a specific sub-set of authenticated clients should also be able to get:

    { "book": {"book-name":"abc", "author":"someone"}, "private-info" : {"book-status":"on-loan", "price":"$20"} }

For a given book, any suitably authorized client can also access the "private info" via a direct HTTP GET /library/books/{book-name}/private-info.

Now, assuming a suitable client authentication scheme is in place, I cannot help but think that the HTTP GET /library/books/{book-name} above is actually looking like two API's, distinguished by authorization state on the server regarding authentication. This seems not very RESTful.

Perhaps it would be better to keep the base GET book API the same for all without ever having any "private-info", while offerring authorized clients only access to the private-info URI and returning 403 to all others?

How does this type of conditional data access typically get handled with REST APIs?

Upvotes: 3

Views: 2177

Answers (2)

David Brossard
David Brossard

Reputation: 13834

I recently answered a similar question. You can find my answer here.

The bottom line is: You should try to separate business logic from authorization logic always. This means you want to externalize your authorization. There are several ways of doing that.

In your particular case, imagine the list of sensitive fields that only a subset of clients can view changes over time, that would potentially require a rewrite of your API. If you decouple authorization logic from your business logic (API) then you can easily update authorization logic without having to rewrite any code. This is called externalized authorization management (see this great Gartner paper on the topic).

As part of my day-to-day job, I help clients secure APIs and web services using XACML. The best practice is always to keep concerns separate.

Upvotes: 1

Jørn Wildt
Jørn Wildt

Reputation: 4482

There is nothing inherently wrong with your approach - it makes good sense to hide information as you suggest based on the user's authorization. REST says nothing about this - the representation of a resource may depend on user authorization, moon phase or what ever else you can think of.

You can although improve caching if you extract the private information to a separate resource. In this case you would have some rather static content for /library/books/{book-name} which can be cached on the client side. Then you would have /library/books/{book-name}/private-info which would be more volatile and user-dependent - and thus not easily cachable.

Building on this you can include a link to the private information in the original resource:

{
  Title: "A book",
  Author: "...",
  PrivateInfoLink: "http://your-api.com/library/books/{book-name}/private-info"
}

The benefit of this is two-fold:

1) The server can leave out the link if the client does not have access to the private information and thus saving the client from a unnecessary round trip to (not) get the private info.

2) The server is free to change the private-info URL if it needs so later on (it could for instance be different URLs based on the user authorization).

If you want to read more about the benefits of hypermedia then try this: http://soabits.blogspot.dk/2013/12/selling-benefits-of-hypermedia.html

Upvotes: 1

Related Questions