RESTful API authorization on entities/resources? - api

I am working on an API in a system that has very complex access control rules. Often times there are complex SQL queries required to determine if a user has read or write access to a particular resource. This causes a lot of complexity and redundancy in our client applications as they have to know all these rules in order to determine whether to present the user with CRUD options for each object.
My goal is to reduce much of the complexity on the client side and house all the complex logic in the API. This way new client applications written against our API can avoid re-implementing the complex access rule logic on their side when ensuring that the UI only presents valid options to the user.
I am not sure what the best way is to handle this. I'm considering two different options but I don't know if there is a better or more standard way to expose generic access information to callers of an API.
Option 1
When a caller makes a GET request on a resource entity or collection of them, every returned entity will return an _allowed_actions field attached, which is an array of actions the caller is allowed to perform on that entity. For example, requesting a Listing object may result in the following response.
GET /listing/5
{
"id": 5,
"address": "123 Foo Street",
"city": "New York",
"state": "New York",
"price": 457000,
"status": "pending",
"_allowed_actions": ["READ", "UPDATE", "DELETE"]
}
Still unsure how to relate to clients whether they have the authority to create instances of a resource entity using this method, but perhaps the client will simply need to maintain enough understanding of the permission structure to determine this on its own. The access rules around creating instances are typically less complex than the READ/UPDATE/DELETE access rules so that doesn't seem too bad.
Option 2
Create a meta-API, which clients can make requests to in order to determine what actions they can perform on each resource. For example, checking what the client can do with a listing:
GET /access-query/listing/5
{
"allowed_actions": ["READ", "UPDATE","DELETE"]
}
And checking what options are allowed for listings in general, including CREATE:
GET /access-query/listing
{
"allowed_actions": ["READ", "CREATE", "UPDATE", "DELETE"]
}
The benefit of this approach is that it allows callers to have a full understanding of what they can do on every resource in a generic way. This way clients wouldn't have to understand that the "create_listing" permission AND a non-probationary user status are required required in order to create listings. They can simply query for this information ahead of time.
The downside to this approach is that it increases the amount of requests. Rather than require clients to have an understanding of the permissions logic, they now have to query once to determine what they can do and a second time to do it.
I don't particularly care for either of these methods but they're all I can come up with at the moment. Is there a better way to go about this?

What you are looking for is fine-grained, externalized authorization:
fine-grained: you want to create authorization policies that take into account multiple parameters or attributes and possibly relationships between the client (the requestor) and the targeted entity e.g. a listing in your case.
externalized: you want to decouple the business logic from the authorization logic. In your question you complain about how complex the code and the SQL statements are becoming. This is a direct consequence of not clearly separating business logic from authorization logic.
There is a model called attribute-based access control (ABAC) that defines an approach to fine-grained externalized authorization. NIST, the National Institute of Standards and Technology, has produced a report on ABAC which you can read online.
OASIS, the organization for the advancement of structured information standards, has defined a standard called XACML (eXtensible Access Control Markup Language) to implement ABAC.
XACML brings you:
an architecture as illustrated below
The policy enforcement point (PEP) intercepts your API calls. It protects your API, inspects the messages and sends an authorization request to the policy decision point (PDP).
The policy decision point (PDP) evaluates incoming authorization requests from the PEP against a set of authorization policies written in XACML. The PDP eventually reaches a Permit or Deny decision. To reach decisions it may need to look up additional attribute values from databases, web services, LDAP, or files. These are called policy information points in the architecture.
a policy language: the XACML policy language is attribute-based which means it uses attributes to define what can be allowed and what is not. For instance, you could define rules such as:
a real estate agent can see all the listings if and only if the listing location == the agent location
a real estate agent can edit a listing if and only if he/she owns the listing
a real estate agent can close a listing if and only if the listing's item is sold and if and only if the agent is the person that sold the item.
a request/response scheme: XACML also defines a way to query the PDP and to get responses back. A PDP can be queried either via single questions or via multiple questions in a single request e.g.:
Can Alice view listing 123? Yes, permit.
Can Alice view, edit, or delete listing 123? Permit; Deny; Deny.
With a XACML-based approach, you get to maintain your business logic and your API separate from the authorization logic. This has several benefits:
you can always reimplement the API and keep the same authorization model
you can easily expand your API without having to rewrite the authorization
you can change your authorization logic independently of your code
you can audit your authorization logic more easily
your authorization logic is technology-neutral. It works for REST APIs, web services, databases, and more
I recommend you check out the following resources:
the OASIS XACML website
the ALFA plugin for Eclipse - a free tool to write XACML policies.
The XACML developer community
There are both vendor and open-source implementations of XACML:
Axiomatics is a vendor solution that provides both .NET and Java XACML implementations
SunXACML is a long-standing open source Java XACML implementation
HTH,
David.

Not trying to resurrect an old question, but I came here searching for almost exactly the same thing and wanted to add a solution that I think is more RESTful.
I haven't actually implemented this but think it may help others who come here...
Your second option is very nearly what I think should be done, but instead of a get use the OPTIONS verb to your resource which will then return an "allow" header with a list of available verbs for that resource.
OPTIONS /listing/5
Assuming your resources are fine-grained enough for this to make sense, then you would know if you can make a POST/DELETE

Related

What is the REST path naming convention to a nested resource that belongs to the authenticated user?

When an authenticated user wishes to access a resource which he exclusively owns, it seems redundant to specify the user id in the URL path.
Thus, in the following examples, which is the more appropriate way to name my API endpoint?
Example 1
User wants to change profile pic
PUT /users/{id}/profile-pic
or
PUT /profile/profile-pic
Example 2
User wants to add a hobby to his profile
POST /users/{id}/hobbies
or
POST /profile/hobbies
It's a joy to see people paying attention to their API design in terms of URI and responses. An API that is not well designed is going to quickly die since people will avoid using them.
Even if it's not going to be public and no one will use it aside from yourself or your team, think of your colleagues and your future self and take some time to think about how your URIs will look like.
Back to your question my friend, according to the hands-on restful API design patterns and best practices book, that I invite you to read,the REST API is composed of four unique archetypes, as
follows:
Document: The document is the base for a resource representation with a field and link-based structure.
https://api-test.​lufthansa.com/​v1/profiles
https:/​/api-test.lufthansa.​com/​v1/​profiles/​customers
Collection: A collection is also a resource, and it is a directory of resources managed by the API providers or servers.
https:/​/api-​test.​lufthansa.​com/​v1/​profiles/​customers/accountbalance
https:/​/api-​test.lufthansa.​com/​v1/​profiles/​customers/memberstatus
Stores: A store is a resource repository managed by the client. The store allows the API client to put resources in, choose URIs for the resources that get added, get them out, and delete them when it decides.
http:/​/api.example.com/cart-management/users/{id}/carts
http:/​/api.​example.​com/​song-​management/​users/​{id}/playlists
Controller: Controller resources are similar to executable methods, with parameters and return values. REST API relies on controller resources to perform application-specific actions that do not come under any of the CRUD methods.
POST /alerts/245245/resend
So, in your case, you can follow the API design of GitHub API. Look how they are retrieving the projects of an organisation. Yours would look this way:
PUT /users/{id}/profile-pic
POST /users/{id}/hobbies
I'm sorry for making it long, I wanted to base my perspective on something concrete.
When an authenticated user wishes to access a resource which he exclusively owns, it seems redundant to specify the user id in the URL path.
It shouldn't; the semantics of a resource identifier and the semantics of an Authorization header are different.
The fact that only Bob can get a copy of /profile/Bob is a matter of access policy, not message semantics.
Review Fielding's definition of resource. "Bob's profile" and "Alice's profile" are distinct nameable information (assuming for the moment that Bob and Alice are themselves distinct) and therefore should have different identifiers.
That's the "RESTful" answer.
In practice, HTTP has special rules about authentication, and the handling of authenticated requests means that you'll probably "get away with" treating the Authorization header as part of the identifier of the resource (particularly in the case where an authorized user is only allowed to access their own resource hierarchy).

Is the appropriate way to fetch user roles/permissions/information from an ID Token or an API endpoint (or other)?

When creating an Angular web application that also has a backend API, I feel like there are a few different options when it comes to getting User Info such as roles/permissions/display name/email/etc.
We can use an ID Token to store user claims like this. That token can be put into local storage or a cookie and the Angular app can read it and render the UI/guard against unauthorized route navigation/etc as soon as the app spins up (since the ID token is available right then and there).
We can NOT use an ID Token for this information at all and instead have an API endpoint that we have to call every page re-load to fetch this data. The server would decode our access token/ID token and return the data in JSON format.
Lastly, there could be some hybrid solution where basic User Info like names/emails are stored int he ID token and available right away, but user permissions (which could be a larger payload and maybe not wanted in a token that should be small) could be fetched via an API
Is there maybe a 4th option I didn't think about?
I haven't been able to find many conventions around which of these options is the best. I like the ID token option as it requires no "blocking" of the UI until the API request is done making the page load that much faster, but I'm not sure if that goes against other conventions.
All your approaches rely on a permissions-based system where you would have been granted permissions upon login. These are sometimes referred to as birth rights since they are typically given when the user is created or whenever their permission sets change. The typical way to carry birth rights around is to have them as scopes / assertions inside an identity token (e.g. OAUth 2.0) that you pass along from service to service.
You can also have your applications retrieve additional permissions / roles / entitlements from a backend store (a database for instance) based on the user ID so that you know what your user can or cannot do.
So far this is essentially role-based access control / permissions-based access control.
The main challenge with that approach is role explosion / permissions explosion as well as token bloat (too many permissions in the token) and administration pains - you have to assign roles and permissions to users all the time. You have to deprovision. It becomes a management nightmare and a risk you may have the wrong permissions set for users. You then need to think about identity and access governance as well as recertification. Heavy.
What's the alternative?
You definitely need some roles - yes - but they should be kept to a minimum - essentially the business roles you need in your apps e.g. a doctor, a nurse, a non-medical staff rather than doctor_hospital1_unitA.
You should then express your authorization as plain-old English policies using any number of attributes - not just user attributes but also contextual information (time, location), resource information (what type of object, who owns it, where is it? How sensitive is it?), and action information (view, edit, delete...).
Sample Policies
A doctor can view a medical record if they are assigned to the patient the medical record belongs to
A nurse can view a medical record if the medical record is in the same unit as the nurse
A non-medical staff can view the financial section of a medical record but not the medical section.
Attribute-Based Access Control
Following this approach is called attribute-based access control (abac). In ABAC, you clearly decouple your app from the authorization process. Authorization is expressed as policies rather than code which makes it easier to:
update
audit
review
How to implement?
You have several options to implement ABAC (from open-source to commercial). You can go down the XACML (xacml) path, the ALFA alfa path, or others. They all have similar architectures with:
the notion of a policy decision point (PDP): a service that evaluates the authorization requests against the set of policies you defined and produce decisions (Permit / Deny) that can be enriched with additional information e.g. order to do two-factor Authentication.
the notion of a policy enforcement point (PEP): an interceptor that sits in front of or inside your API that will send an authorization request to the PDP.
I've written about the architecture more in detail in this SO post.
ALFA Example
In ALFA, a sample policy would look like:
policyset viewMedicalRecord{
target clause object == "medical record" and action == "view"
apply firstApplicable
policy allowDoctors{
target clause role == "doctor"
apply firstApplicable
rule allowAssignedPatient{
permit
condition patient.assignedDoctor == user.name
}
}
}

Custom Role based authentication

I have a very complex requirements to implement the roles and permissions in my asp.net mvc 4 application. I know about ASP.NET Identity authentication but that does not fit into my requirements.
I have 15-20 controllers in my applications which have their respective views, some of views have partial views which are being handled in Jquery code and loaded from there.
Now I have below requirements:
1)Some of controller are accessible to a perticular role(s) only.
1) Some of views in a controller are accessible to a perticular role(s) only.
2) In a view for a Grids only some of columns and actions like Edit/Create/Delete are accessible to a perticular role(s) only.
I am thinking to implement checks on controller , actions and views on the basis of role but that can lead into a problem when I have multiple roles and custom roles in future. What can be best way to implement this kind of solutions. Any suggestions will be appreciated.
Every time you have "complex" authorization requirements, it's a pretty good indication that "identity-centric" access control is not enough. What's identity-centric? Authorization that relies on user metrics (identity, role, group) only.
Also, in your question, you list the fact that you do not know what the future holds. You do not know what other custom roles you need to implement.
All this means you need to extend your existing RBAC implementation with attribute-based access control (abac). ABAC gives you 3 interesting elements which you do not have in RBAC:
A policy language. You can express complex authorization challenges using this policy language (either of xacml or alfa). In particular you can express things like Permit if user department==record department.
An architecture: the architecture identifies key components with specific responsibilities. For instance, you have a Policy Decision Point (PDP) which produces authorization decisions. You have a Policy Enforcement Point (PEP) which is the piece that sits in front of or inside your application. The PEP protects the application.
a Request / Response scheme between the PEP and the PDP. The standard format is a Yes/No question as shown in the diagram below. JSON can be used to encode the requests.
From your point of view, you have two options. Either:
Implement claims-based authorization. This is available OOTB in .NET
Bring in XACML. I'm not sure .NET has any native libraries but there are SDKs out there.

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}
Any authenticated client should be able to get (JSON) data for the book, like:
{
"book":
{"book-name":"abc", "author":"someone"}
}
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?
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
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.

Statelessness of a REST api with authenticated users

I'm currently designing a REST Http api. (With HATEOAS stuff, to make clients "simpler", and avoid clients to do complicated things, instead of letting the api tell them what to do ...)
Because of the social characteristic of the app, in order to interact with the application, users need to be authenticated, and each user will have a slighty different "view" of the data.
We'll take twitter as an example, it will be easier for everyone.
To authenticate users, we'll use OAuth, easy.
So, in the client (ios app...), a random user would maybe seeing a list of users should see:
Adrien: Following
John: Not Following
Rambo: Not Following
And another user would maybe see:
Adrien: Following
John: Not Following
Rambo: Following
To achieve this, the first solution would be for the client (in oauth term, the iphone/web/etc app), to get a list of all the users the authenticated user follow, and each time the client displays a list, compare each user with the list of followed users to know if it should display "Not Following" or "Following".
The requests/responses would be:
GET /users
Authorization: OAuth token...
[
{"id": 1, "name": "Adrien"},
{"id": 2, "name": "John"},
{"id": 3, "name": "Rambo"}
]
and
GET /users/{myid}/following
Authorization: OAuth token...
[1, 3, 25, 1210, 9]
This seems to be quite, stateless. Good.
Now what if i want to make client developers life easier, and embed directly in the user list response, the relationship of each user, relative to the authenticated user:
GET /users
Authorization: OAuth token...
[
{"id": 1, "name": "Adrien", "relationship": "Following"},
{"id": 2, "name": "John", "relationship": "Not Following"},
{"id": 3, "name": "Rambo", "relationship": "Following"}
]
So, questions:
It seems to break the "stateless" thing, does it really break the REST stateless constraint ?
Next, do you think it is a good or bad practice for an api to do this ?
You should definitely embed the relationship in the user list response. It would be bad practice to force the clients calculate it.
This does not break the stateless constraint of REST as it's the interactions that are stateless, not the systems. The server will almost always have to store and maintain state. For instance the server will need to maintain state of who is following who.
Finally, I think you are not fully getting the "State" part of Hypermedia As The Engine Of Application State. Basically, the resources are state machines. When you GET a resource, the valid state transitions are presented has hypermedia controls (links and forms) in the response. It's by following these links and submitting the forms that the client can change the state of these resources.
Including the description of the relationship type in the response body is not breaking the stateless constraint. The stateless constraint means that the web server can respond to the request without being dependent on any previous request (as has been mentioned by Tom, Jacob and kgb).
I'm not qualified to say whether what you're doing is a "best practice" or not, but in general Roy gave the following reasons for and against making your API stateless (see section 5.1.3 of his dissertation). Like many things in life there is a trade-off:
Problems with a Stateless System
Requests may need to be larger. Since data is not stored on the server between requests, each request may need include the same things over and over again.
In a stateless system, the server is dependent on the client maintaining the state correctly.
Benefits of a Stateless System
You know what a request is trying to achieve based solely on its content.
Reliability, since it "eases the task of recovering from partial failures". See reference 133 cited in Roys dissertation for more info.
Improved scalability. Managing state between requests, particularly in a distributed environment can be quite complex. The first thing that comes to mind here is ASP.NET InProc session state, fine for a single server, single process instance, but it doesn't scale very well.
RESTful Resources
Also, according to Roy's definition of a resource I'd take issue with how I think you're defining your resources, with each user getting a slighty different "view" of the data. Roy defines a resource as a membership function that varies over time (see section 5.2.1.1 in the dissertation). The user list resource you've defined above varies by both time and by the Authorization header. Two different clients requesting /users at the same time would most likely end up with completely different results. This will make caching the results more difficult.
EDIT: Using the HTTP vary header would allow it to be cached.
If you think adding "relationship" property to users breaking stateless constraint, then adding it when "/following" is in the request, would be breaking it too.
I would say "stateless" means no response depends from the other requests/responses.
HTTP is a stateless protocol, but it can store quite a lot of data about the user in the request/response headers(and i am not talking about sessions/cookies)
From Roy Fieldings Architectural Styles and
the Design of Network-based Software Architectures:
3.4.3 Client-Stateless-Server (CSS)
The client-stateless-server style derives from client-server with the additional
constraint that no session state is allowed on the server component.
Each request from client to server must contain all of the information necessary
to understand the request, and cannot take advantage of any stored context on
the server. Session state is kept entirely on the client.
Link: http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
So you embedding entity data directly in the response does not make your solution non-stateless.
On good practice:
It's a lot better to actually serve the user data than a list of numbers for the client to figure out what to do with.
However, depending on the amount of data for each user, you could consider giving a list of links to the user resource and state the "follow" relation as well. Then the client can fetch the details on the needed users. Which solution you choose should depend on what you believe the client will be needing, you might end up using several approaches.
I don't see the correlation between embedding the "relationship" information into the /users resource and the stateless constraint. So I see no issue.
However, I would argue you are breaking the "identification of resources" constraint.
/Users for you and /Users for me is going to show a completely different set of relationships. I would argue those are two different resources and therefore should have distinct URIs.
There are some scenarios where you can change a representation based on who the user is (for security reasons for example) but this case is just too much change for my liking.