How should I secure this public API? - rest

I have built a REST API that will be integrated into existing consumer booking systems/applications and enable their clients (end users) to book additional goods/services that my company provides.
For example, end user books accommodation and, if the booking system they used has fully integrated our API, that user can also rent a car for his trip.
So the three parties involved in this B2B2C business (in a mini-flow chart) are:
API (My company) <--> Client (Booking Provider) <--> (Client's Client) End user
On behalf of the end user, our client (the booking provider) can call the following of our endpoints:
Check product availability
Place order
Cancel order
We want booking providers to 'install' our API services in their system, thus providing our services to their end users, and then not really have to worry about it (i.e. not have to login all the time to reauthenticate). My question is, how would you protect these endpoints?
Api Key - so the booking provider hardcodes the key in their requests?
JWT - the booking provider has to hardcode their login details to automatically retrieve an access token everytime there is a session?
Oauth - same issue as JWT?
None of these seem optimal. If you have any advice I would be very grateful.

In my opinion there is not much difference between Api Key and JWT/OAuth in the scenario you described.
Personally I would choose an Api Key, or if you really need to maintain a higher level of security you could think about a certificate based mutual authentication.

Related

Making API requests to a 3rd party that requires authentication

Here is my scenario. Imagine there is a Yoga studio that uses a professional booking and reservation system that exposes an API. Through this API an application can make a reservation for a client. The API takes the client's userid and password to make the reservation. The booking API doesn't use OAuth or any social media sign-ins.
My desire is to create an Assistant Action that would retrieve the list of classes and allow the client to make a booking.
My puzzle is what design/architecture to look towards to supply the userid/password pair required by the booking API.
How have others solved this puzzle?
Should I store the userid/password as "user state" associated with the action?
First, you should have a conversation with the API provider about why they don't provide an OAuth-based solution. This is a security vulnerability waiting to happen, if it hasn't already.
Second, you need to think very carefully about your own risk profile in this case:
Google does not allow you to collect credential information (ie - passwords) through your Action.
Because of this, you must use Account Linking to authenticate them.
This means that you will need something (ie - a database or data store) to manage their account on your side.
This database would be a good place to keep the username/password you need to use for them for the API...
...but it now means that you need to take extreme care about protecting this database.
You don't really say how this API allows for accounts to be created and managed. If these accounts are just used for you (ie - the user doesn't necessarily see them), then you can mitigate some of that risk by treating the username/password as an opaque token that you manage and generate and that the user never sees.
If this is something that the user is aware of, then you'll need to approach the account linking in one of two ways:
Have them log into your service via an app or webapp using this credential info that you will need to save (ack!) and then link to the Assistant using OAuth.
Have them log into your service via an app or webapp using Google Sign-In, which will carry over to your Action. Then have them provide the credential info for the API, which you will need to save (ack!).

Microservice Architecture design for subscription

Would like to get some opinion on designing a system with subscription model using microservice architecture.
We implemented an identity server which authenticates and authorizes
users, and stores their subscription profile. (i.e. resources they can
access like which magazine and issues)
on the resources service, the subscription profile will be used to
filter their eligibility. example, if their subscription starts from
Year 2018, then this will take effect and return only year 2018 data
to the users via REST API.
Is this a standard/proper microservice architecture implementation? or any better ways to design this?
I'd argue no, especially if you want to embrace the principles of microservices - you're storing authorization and application domain specific data in your Identity server. Your IDP should only be concerned with authentication concerns.
I'd suggest a separate service or set of services for managing and retrieving this additional information that is linked to user entities in your IDP via a correlating ID (e.g. subject ID, email address, account code etc). This service would own its own data and be consumed by anything which needs to know about subscriptions and the like.

API Authentication - Clients (consumers) vs. local users

I work for an ecommerce site and we are looking to expose much of our core functionality via a set of APIs. We plan on re-writing some of our own public facing applications (e.g. the main shop website and our mobile app) to call these new APIs also. We also want to offer some of these APIs out to third-parties who want to integrate with us.
My first question is - what is a suitable authentication method for these APIs? Everything I read is about OAuth, but am I right in saying that this doesn't fit in this case as we're not looking to use another log in system (e.g. Facebook, Google) but rather restrict access to our own API (so maybe an API key or JWT solution would be better?)
Secondly, our current website has it's own user accounts system. How do you offer /user endpoints (like GET user/1235/paymentmethods) in an API like this? Surely the actual user (website customer) needs to authenticate somehow in order for the given API consumer to access their data.
I've spent the last 2 days reading about this but I'm at a loss as to how to go about this! Any help much appreciated.

Access control based on data filtering instead of request authorization

Standard way to control access in a multi user service is to provide as many service methods as necessary, where each service method has concrete results and access permissions.
For example,
Moderator is authorized to call GetModerationAwaitingPosts service method to access posts from any visitor awaiting for moderation
Visitor is authorized to call GetOwnedPosts service method to access only his own posts including draft and moderation awaiting posts
Visitor is authorized to call GetModeratedPosts service method to access only moderated posts from all visitors
But there may be another approach - single service method GetPosts to request posts that the requester is allowed to see.
Any logged in user is authorized to call this method.
Posts are first filtered according to the role of the caller.
Then posts are filtered according to parameters passed in GetPosts method or filtered on client side.
This approach is used, for example, in WCF Data Services through Query Interceptors.
How is approach to filter data based on user inside service method named and treated in different architectures and methodologies, like SOA, REST, CQRS? Is it a solid solution?
Are there any books / articles where difference between these approaches is considered in details?
As for me, I find it really strange and unusual when results of a request depend on the requester.
Yes, there is an access control paradigm called attribute based access control (ABAC, abac) which implements data-based, context-based authorization that uses information about the user (role, department, age, location...) about the resource (owner, classification, type...) action (view, edit, delete), and context (time, IP address...)
ABAC will let you implement policies e.g.:
Medical use cases
doctors can view the medical records of patients they are assigned to
nurses can edit the medical journal of a patient in the same deparment
Finance use cases
A teller can view the accounts of those customers in their branch
A teller can approve a transfer up to their approval limit
ABAC provides an architecture as depicted below.
In the architecture you have the notion of a PEP or policy enforcement point which you can use to secure anything from GUIs, APIs, web services, micro-services, ESBs, and databases.
The PEP calls out to the PDP or policy decision point which is at the core of the architecture. The PDP uses a set of policies to determine whether access should be granted or denied. It can also use external sources of attributes, PIP or policy information points, to help in determining whether access should indeed be granted.
There is one language which implements ABAC today. This language is called XACML (xacml). XACML gives you:
the architecture
a policy language
a request / response scheme
With XACML you can create JSON authorization requests, send them off to the PDP and get a JSON response back. It's an extremely lightweight way of getting a response back.
This means you can either
grant or deny access to a given record, or
filter those records a user can get access to as stated in your requirement

Client Facing REST API Authentication

I have seen many different posts regarding different solutions for authenticating a RESTful API and I have some questions, given this current scenario.
I've built a REST API that will allow clients of my software service (we are a B2B company) to access resources programmatically. Now that I've got the API working properly, I'd like to secure it in the most standardized way possible. I need to allow access to certain resources based on the caller of the API. That is to say, not all users of the API can access all resources.
I have URLS available in the following formats:
https://mydomain/api/students
https://mydomain/api/students/s123
https://mydomain/api/students/s123/classes
https://mydomain/api/students/s123/classes/c456
So far I've come up with these possible solutions:
Provide a unique key to each client that they can use to ultimately generate an encrypted token that will be passed as a GET parameter at the end of each REST call to (re)-authenticate every single request. Is this approach too expensive
https://mydomain.com/api/students/s123?token=abc123
Provide a value in the HTTP Authorization Header as seen here. Is this almost the same as #1? (Except I can't paste a URL into the browser) Do people use these headers anymore?
Use OAuth 2 (which I'm still a bit unclear on). Does OAuth 2 actually authenticate the client as a logged in user? And doesn't that go against the spirit of a REST API being stateless? I was hoping OAuth was the proper solution for me (since it's a public standard), but after reading up on it a little bit, I'm not so sure. Is it overkill and/or improper for REST API calls?
My goal is to provide an API that will not have to be changed for each client that wants to consume the API, but rather that I can provide a standard documentation made available to all of our clients.
I'll be happy to post additional details if I've been unclear.
There are 2 type of clients you probably want to prepare your API:
trusted clients - Which are written by you. They can have the username and password of the actual user, and they can send that data to your server with every request, possibly in a HTTP auth header. All you need is an encrypted connection by them.
3rd party clients - Which are written by some random developer. You can register them in your service and add a unique API key to each of them. After that if an user wants to use their services, you have to show her a prompt in which she can allow access to the 3rd party client. After that the 3rd party client will be assigned to the user's account with the given permissions and it will get an user specific access token. So when the client sends its API key and the user specific token along with the request, then it sends the requests in the name of the user.
OAuth can help you to control the second situation.
Your URLs do not have a meaning to the clients. By REST you have to decouple the clients from the URL structure by sending links annotated with semantics (e.g. link relations). So your documentation does not have to contain anything about the URL structure (maybe it can be useful for server side debug, but nothing more). You have to talk about different types of links. By generating these links on server side, you can check the permissions of the actual user (or 3rd party client) and skip the links which she does not have permission to follow.