Developing a REST API implies dedicating an important effort of resources and people. But how to expose my API in a secure way?. If we want to market our API, security acquires special importance, and if we move in the Health sector, this issue is absolutely key.
Implementing a good layer of security of our API will avoid many problems, although it will require from us an important effort.
In this article, we introduce the main authentication and authorization methods that we can use to secure a REST API, and we will discuss other aspects related to security that we must keep in mind.
Finally we will see a good alternative to drastically reduce the effort required to market our REST API safely.
Tabla de Contenidos
- 1 INTRODUCTION
- 2 BASIC ACCESS AUTHENTICATION
- 3 DIGEST ACCESS AUTHENTICATION
- 4 COOKIES BASED AUTHENTICATION
- 5 TOKENS-BASED AUTHENTICATION
- 6 AND THE AUTHORIZATION?
- 7 API KEY-BASED METHODS
- 8 OAUTH 2.0
- 9 USE A SECURE PLATFORM
First, let’s set two basic and important concepts: authentication and authorization.
Authentication methods guarantee that the users who access our resources are who they say they are.
Authorization methods ensure that the authenticated user who accesses a certain resource is authorized for that resource.
That said, there is a particular aspect of the design of REST API (2) that affects security:
REQUESTS MUST BE STATELESS
From the developer’s point of view, this affects how to implement the confirmation of the identity of the user, that is, the authentication, since in each request we must guarantee that the client has permission to access our resources.
When developing a web application, this aspect is not essential. It is usually obvious, since it is a human who is interacting with the application from a web client.
In these cases, the session can be maintained with the user’s browser using a cookie, storing the session identifier on the server side.
But when we deal with REST APIs this is not desirable. On the client side, what we have is another software.
BASIC ACCESS AUTHENTICATION
The solution is, instead of managing the status on the server, returning a token that the client will send in each new request and that the server will be able to interpret.
But let’s go step by step. In the following diagram we can see the interaction between a web application (or our browser) and the backend where the API endpoint is published.
Figure 1: Client access to API
In the first step, the application must send the API access credentials by using a header (header Authentication) and this is where we should start to be careful.
If communication with the API endpoint is not done through HTTPS, someone can listen and read the username and password, even if some coding method is used (usually a user base64: password).
This mechanism is called Basic Access Authentication (3).
Basic Authentication is not very secure for two reasons:
- firstly, base64-based coding is easy to break, and once obtained, any client can use the API,
- and secondly, the resource accessed is not checked. So the same request is valid for any resource. You just have to try several times and determine if you have access or not.
DIGEST ACCESS AUTHENTICATION
For these reasons, another method arises: Digest Access Authentication.
The server where the API runs, randomly generates a series of values. These values are sent by different headers, in response to a first request that is answered with a code 401.
The client generates a hash with the user, the password, the desired resource and the values received from the server.
This hash cannot be altered or decoded by a third party, and only client and server have all the elements to generate it and be able to trust each other.
As we can see, things go complicated as we move forward … but what about the following requests?
Should we send the credentials or hash again with each request?
COOKIES BASED AUTHENTICATION
The answer is no. We just have to store a session id on the server, and inform the web application to use it in each request.
To avoid this we can include that session id in a token along with more information. This token is unalterable and unique.
This mechanism is known as Token-based Authentication (Token Bearer).
There are many mechanisms to generate that token, but the most widespread and documented is the JSON Web Token (JWT) (4).
It is a string consisting of three parts (header, payload and signature), which are processed by a hash algorithm with a secret key.
Wow!!!, how much work to make sure that nobody discovers our credentials and that they cannot impersonate us in each invocation of the API. Luckily there are many libraries that make this work easier for the developer.
AND THE AUTHORIZATION?
But that’s not all, since we must now deal with the Authorization, that is, based on the access credentials we can determine whether or not the user can consume a specific resource.
Naturally, it all depends on what type of operations can be performed with our API.
There are APIs that offer read-only information and little or nothing sensitive, such as a weather prediction APIs.
In these cases, we may be interested in sharing that resource without requiring authentication or authorization.
Other times, they will be operations that affect sensitive data or important for our business, as in the case of APIs for Health.
In these cases authentication and authorization are most likely required, because some operations will be able to write data and we must control which user can perform them.
Let’s see what methods we can implement to manage the authorization.
API KEY-BASED METHODS
In this case the tokens obtained in the authentication process can be used to handle an authorization table, in which we indicate which resource can be used by the user and for which operation.
The problem remains that there is a direct relationship between the application that will consume the API and the user used for authentication.
Because of this, the application must manage if its users have permission to view and manage the information returned by the API.
Ideally, the authorization management should be implemented in the API, but according to roles or permission groups that a user requesting a resource can do.
OAuth 2.0 (5) is an authorization framework that has become a de facto standard in the use of APIs.
It allows delegating authorization to access APIs without having to provide user information.
This is based on the concept of access token, and defines a series of flows and the use cases in which they are applied. The flow we must implement depends on our API.
To understand them, we need to know a little about the terminology used.
The main actors involved in the flows are:
- Resource owner: Party that can authorize access to protected resources. It may be an authorization of certain resources and not others. It is usually a person.
- Client: It is the application that accesses the protected resources of a user with the authorization of the same.
- Provider / Server:
- Authorization server: Validates user and credentials; and generates access tokens.
- Resource server: It is the API that exposes the data that you want to access.
Figure 2: Actors
The scope is a set of parameters involved in negotiating authorization and consent. It allows to determine what access is requested and what access is authorized.
The tokens are credentials used to access protected resources. Depending on which phase of the negotiation we are in, there will be different types of tokens that will be exchanged with the different actors.
Let’s see how a flow of information would be between the actors:
Figure 3: Abstract Flow
The first step is to obtain permission from the API owner to access the resources.
This step is called Authorization Grant and there are four defined flows (Grant types).
Each of the types of authorization is designed to solve a business case that we can find. We will choose ours according to the type of our API consumer, the degree of trust and the degree of interaction of the end user in the process.
Let’s look briefly at the different Grant types.
Client credentials Grant
In this case the client belongs to the owner of the resource, so there is a complete relationship of trust between the two.
Therefore, the identity verification phase can be avoided, the flow being reduced to only two steps.
- The client application sends its credentials to the authentication server.
- The authentication server checks the credentials and if they correspond to those of the client application, the access token is forwarded.
Figure 4: Client Credentials
This scheme should only be used in the following cases:
- The consuming application is fully trusted and / or the data that is sent to the users of the application is not sensitive.
- There is an agreement with the API consumer and a secure channel to transmit the credentials.
Resource Owner Password grant
This type of authorization is used when the client application is fully trusted.
User credentials are used to access the API and establish authorizations for access to resources based on the characteristics of this user.
These credentials are not stored in the client application, and are only used to obtain an access token.
This type of authorization is used mostly in mobile applications, where once the application has been downloaded to the terminal, the credentials are entered only once.
Figure 5: Resource Owner Password Credentials
In this case, the flow would be:
- The end user provides their credentials directly to the client application, the application being responsible for authenticating with those credentials.
- The application sends the user’s credentials and the server returns the token.
- The application manages the life cycle of the token and does not ask the user for his credentials again.
This flow will be used in the following cases:
- Web, mobile or desktop applications that are reliable.
- The user consents that their credentials are used for interaction with the resource.
- The API has control of the user’s authorization.
- The communication is client-server type.
In this flow the end user takes a relevant role, since he must:
- expressly consent that the client application can access his data and
- confirm that the authentication token is valid, and that the access token can be forwarded.
This prevents the client application from accessing the user’s credentials, replacing them with an authentication token.
Figure 6: Authorization code
Let’s see how this flow works:
- The client starts the flow by directing the client application to the authorization point (a login interface). The application reports the authorization scope, and the return address where the client application is.
- The authentication server identifies the owner of the resource and establishes whether it authorizes the client to access.
- If the authorization has been affirmative, the authentication server redirects to the client application by sending the authorization token in the redirection.
- The client application sends a request to the authentication server with the received token and its credentials to obtain the access token.
- The server checks the authorization token and application credentials, and sends the access token.
This flow is especially used when:
- The client application is not trusted, such as mobile or desktop applications.
- When you want to connect the API to third-party applications.
This last case is identical to the previous one, but instead of using an authentication token, the access token is used directly as a response.
Figure 7: Implicit Grant
We see how this flow is carried out:
- The client starts the flow by directing the agent (usually the web browser) of the resource owner to the endpoint of the authorization server. The client includes the authorization scope, return address and local status.
- The authorization server authenticates the owner of the resource and establishes client access.
- The agent follows the redirection based on the return url, which includes the access token, This token will be stored and managed during its life cycle.
- With the access token, the client application is able to access resources.
When we should use this flow:
- The basic case is the applications of a single page (6), that when using only the storage of the web client, this cannot be considered a safe environment.
- When the end user has to have control of access to resources and know where the client application is accessing.
We must indicate that this mechanism cannot guarantee the confidentiality of the access token, so its lifetime is very limited and has no possibility of renewal.
USE A SECURE PLATFORM
At this point, we have shown that enabling authentication and authorization for our API is not something simple and it’s of such importance that we can not ignore.
There are still many other aspects of security that we have not included and that are of equal importance, regarding scalability, availability, countermeasures for denial of service, etc …
Let’s stop for a moment and take into account a series of basic additional recommendations to address security of an API:
- Simplicity: We must look for the simplest solution that best suits the degree of security that our API requires. Adding unnecessary complexity will only lead us to make mistakes.
- Always use HTTPS: This will prevent traffic from being easily intercepted. And if we can use HTTP 2, much better since it will improve performance.
- Use encryption for passwords: we will avoid identifying passwords.
- Use OAuth2 or JWT: they are by far the most used and best documented and supported frameworks.
With these recommendations in mind, we must consider if the needed efforts to implement all security mechanisms on our own platform are worth it.
It is important to evaluate the use of a Gateway solution that protects our resources and facilitates the management of our APIs consumers subscriptions.
We may have the possibility of delegating most of these aspects to a specialized third-party solution that helps us save time and effort, and that allows us to focus on the functionality and usability of our API.
The platform that Nubentos provides with its API Marketplace for Health, incorporates the main security mechanisms discussed above and many others specific for more special use cases.
But it also provides additional features concerning safety:
- Automatic scaling:The platform provides the ability to manage any level of traffic you receive for an API, so you can focus on services and business logic, rather than in the infrastructure maintenance.
- Ability to manage access lists: We can identify attackers and block them, not only attending the source IP but also seeing their type of request and acting accordingly.
- Service quality management:Through the various flow management mechanisms, we can limit the requests coming to APIs providers to avoid saturating the backends. We can limit the requests that a single customer can make, thus avoiding malicious or fraudulent uses.
- Proximity to the client: The Nubentos API Marketplace platform has a globally deployed architecture. This facilitates that regardless of where your customers are, they have a nearby access point, reducing latency times and improving response time.
All these advanced security features are available for free in Nubentos, the best platform to open your APIs for Health to third parties safely.
(8) Basics of oAuth2