Topic

Authentication and Authorization in REST APIs

Author

SB Karunarathne

13 October,2023 • 21 mins read

Nowadays, REST APIs are widely used for building APIs due to their many benefits such as simplicity, scalability, ease of use, and statelessness. REST APIs are commonly implemented using HTTP, making them accessible through standard HTTP requests and responses.

In general, when we build an API, several factors need to be considerd. Usage, scalability, performance, versioning, and security are some of them. Among them, securing APIs is crucial in API access management. A secured API not only prevents unauthorized access but also offers numerous other advantages such as integrity maintenance and regulatory compliance. As technology advances, API developers should continually strive to fortify their APIs against potential threats from unintended sources.

When we consider API security, it’s important to manage it at different layers such as the transport layer and application layer. As the REST APIs are used using the HTTP that operates at the transport layer (OSI Model - Layer 4), we can enhance the security of the transport layer by using HTTPS. HTTPS helps to have end-to-end encryption in the wire when the API requests and response are transmitted over the network. On the other hand, when dealing with the application layer security, the developers have to think about authentication, authorization, protection against malicious attacks, rate limiting, as well as service availability in the face of attaks such as DoS and DDoS. The main focus of this article is to give a basic understanding about securing the APIs and how Authentication and Authorization can help to make this successful.

Authentication

Authentication is the process of verifying the identities of users or clients based on a particular security implementation. To prove their identity, users or clients must provide credentials, which the security system then evaluates to determine their validity. Primarily, the authentication process allows us to accomplish the following:

  • Access Control: User should have the valid credentials and proper permission to access the resources (APIs).
  • Identification of User: With the credentials provided by the user/client, the identity can be revealed and can be used for the personalized secured access to the APIs
  • Auditing: Based on the information provided by the user, the user's activity can be logged and can be used for audit processes later.

The authentication process can be implemented in different ways and it can be varied based on the requirement. Let’s explore some of the widely used implementations!

API Key Authentication

This is a common approach used in REST where the client sends the API Key along with all the requests (most often the key is sent as a header or a query parameter, which is not safe) and the server validates the API Key and checks whether the request can be authorized. In this approach, usually the API provider generates a unique API key for each client that grants access to the APIs. Following are some of the factors we have to consider when the API Key authentication is used for REST APIs:

  • API Key Confidentiality: API Keys should not be stored in an easily accessible manner. For example, instead of keeping the API Key along with the source code, it is advisable to use a secure place to store it and retrieve it when the program is executed. API Keys should also have their own scope associated to prevent unauthorized API access.
  • API Key Lifetime: The keys should not be long lasting and should be periodically changed and should be expired in a certain period.
  • HTTPS support: Providing the HTTPS support will give the end-to-end encryption between the client and the server to secure the API access.
  • Rate limiting: Limiting the number of requests coming to the server will allow to fair usage and prevent attacks such as DoS and brute force.
  • Monitoring, auditing, and logging: The APIs should be monitored to identify the potential attacks. The request patterns and metrics should be identified and controlled to keep the system safe and healthy. The API access should be logged to identify any exceptions or any attempts to misuse.

Here is a simple sequence diagram that depicts the successful flow of this authentication mechanism.

Article Image

Basic Authentication

With this approach, the username and password will be concatenated (username:password) and encoded with base64 and sent along with each API request. The credentials sent will be validated against the credentials that are saved in the server to grant access. Usually, the ‘Authorization’ header is used to send the credentials where the encoded credentials are prefixed with the word ‘Basic‘, e.g., Basic bXl1c2VxOm15dGFzc3dvrmQ=. There are certain factors to consider when using this approach to authenticate the APIs:

  • HTTPS support: As we are sending the credentials in plain mode, it will insecure if we do not implement end-to-end encryption at the transport layer.
  • Password hashing: The passwords should be hashed and salted before storing in the database to avoid the data breaches.
  • Rate limiting: Rate limiting should be implemented to avoid brute force attacks. The DoS/DDoS attacks will make the system unavailable.

Here is a simple sequence diagram that depicts the successful flow of this authentication mechanism.

Article Image

Token Authentication

In this approach, the client will receive a token, e.g., OAuth2 token and JWT, from the authentication process. That token will be sent to the server along with each request. Usually, the token is sent with the ‘Authorization’ header and the token will be prefixed by ‘Bearer ‘. The server checks the token validity and provides the access to the resources if the token is valid. Under Token Authentication, we will briefly examine OAuth2 and JWT authentication.

OAuth2 Authentication

This is a widely used approach for authentication and authorization of REST APIs. With this method, the third-party application can access data on behalf of users without revealing the credentials. OAuth2 is a result of a collaboration of multiple components/parties:

  • Client: The application that consumes the service of the OAuth2 access token. The client could typically be a web application, mobile application, or any other
  • Resource Server: The server that contains the resources (in our case the APIs) that the client want to access
  • Authorization Server: The server that helps to authenticate the user and generate the access token to the client. User consent and token validation is a part of this.
  • Resource Owner: The user who owns the data and resources that the client wants to access

As discussed above, the authentication server generates the access token and provides it to the client. The client uses the access token in order to access the APIs in the resource server. Usually the tokens are short lived and can have different scopes as per the client needs. In OAuth 2, the ‘grant type’ is used to address different use cases:

  • Authorization Code: This is a two-step process. The client sends the authorization code and exchanges it with an access token. This is more suitable for web applications.
  • Client Credentials: The client provides the credentials and receives an access token. This is commonly used for server-to-server communication.
  • Implicit: The access token is provided without any authorization code. This is suitable for client applications like Web apps.
  • Resource Owner Password Credentials: Client provides the username and password and receives the access token. This is usually used in trusted environments, but not recommended.
  • Refresh Token: Sometimes, we may need to obtain a new access token (may be because of token expiration) and get it without any user interaction. This grant type provides the capability of obtaining a new access token. This grant type enhances the security of the tokens by minimizing the use of long-lived tokens

With the collaboration of the above components, let’s discuss how we can retrieve an access token using OAuth2 using the ‘Authorization Code’ grant type. Please note that it is nearly similar to other grant types (of course there are some slight differences in each scenario):

  • Client initiates the OAuth2 flow by redirecting the user to the authorization server for authentication.
  • User logs in and grants the permissions (scopes requested) if the login is successful If the grant is successful, the authorization server generates an authorization code and returns it to the client.
  • The client exchanges the authorization code or receives the access token directly.
  • Client includes the obtained access token in the API requests and accesses the APIs.

The following sequence diagram shows how a typical OAuth2 request works for the grant type as ‘Authorization Code’.

Article Image

OAuth2 is widely used and secure and suitable for various use cases. We need to have a careful implementation in order to avoid security vulnerabilities. We need to have a proper attention on token management, token expiration, and user consent for a proper OAuth2 implementation.

JSON Web Token Authentication

JSON Web Token (JWT) is a compact, self contained token. This token is used for implementing the authentication as well as authorization in web applications. A Typical JWT consists of three parts:

  • Header: Usually the header contains the token type, algorithm and other useful information.
  • Payload: Generally the payload contains the subject (usually the username), token issued time, token expiration time, and any other useful information like permissions.
  • Signature: This section is used to verify the sender of the JWT and to ensure the message is not changed in the middle.

To create the token, we need to follow the following steps (usually we can use third-party libraries to generate the tokens by providing the required information)

  • Prepare the header component.
  • Prepare the payload component.
  • Prepare the signature component:
    • Encode the header using a base64 encoder.
    • Encode the payload using a base64 encoder.
    • Concatenate the encoded header and the payload with a ‘.’.
    • Sign the above concatenated string with secret using the algorithm specified in the header.
  • Concatenate the header, payload, and the signature using the ‘.’ to create the token.

After the token is created, we can use it for authenticating the APIs. Usually the token is sent along with the ‘Authorization’ header with the token prefixed with ‘Bearer ‘. The most important things to remember when using JWT tokens are:

  • After the JWT tokens are used, they should be properly disposed; if the token is not expired, they can still be used by someone else.
  • The JWT tokens should be short-lived as they can be misused.
  • Better to implement a refresh token mechanism to handle the issue with short lived JWT tokens while taking care of the user experience.

The following diagram indicates how the JWT token is generated and utilized for API execution.

Article Image

Even though token based authentications like OAuth2 and JWT are good authentication mechanisms, there are facts that we need to take care when we use it. Here are some points that need to be taken care of.

  • Token leakage: If the token is not properly protected by the client, these tokens can be used by external parties.
  • Token expiration: Having long-lived tokens is not safe; the tokens can be used by other parties. If the token is short-lived, then the user experience will be bad. We can overcome this problem by implementing the refresh token mechanism.
  • Token revocation: The tokens should be properly disposed after use. Otherwise, the token can be used by external parties and it has a potential risk
  • Token storage: If the tokens are not properly stored, can be vulnerable for cross-site-scripting (XSS) attacks.
  • Token payload: Try to minimize the size to save the bandwidth. Also make sure not to store the sensitive information as it can be easily read by others.
  • Token validation: The tokens should be properly validated for alteration and the expiration should be checked to avoid unnecessary access to resources.

HMAC (Hash based Message Authentication Code)

HMAC involves hashing the request data and using a shared secret key to create a signature. The server verifies the signature to authenticate the request.

Digest Authentication

This authentication approach is somewhat similar to Basic Authentication. But, this is more secure than Basic Authentication. This uses a challenge-response mechanism with hashing for authentication.

Other authentication types

Apart from the above-mentioned authentication types, there are other implementations like Biometric authentication and certificate-based authentication. We can also implement a custom authentication mechanism by combining one or few of above-mentioned authentication types with additional steps. To strengthen the security, it is better to introduce a secondary verification method using multi-factor authentication

Authorization

Authentication itself cannot fully secure an application. For example, the users with generic permissions should not be able to access the admin level features like user management. Here’s where the Authorization comes into the picture. Authorization is the process of granting (or denying) access to specific resources, data, or actions based on the permissions/role entitled as per the authentication. Some of the benefits/purposes of authorization can be be listed as follows:

  • Resource protection
  • Data privacy
  • Fine-grained access
  • Preventing misuse
  • Security

As we discussed above, authorization can be split into two types:

  • Role-based Authorization
  • Attribute-based Authorization

Let’s discuss further on these to get more understanding how each of them handle the authorization for the logged in user!

Role-Based Authorization

In Role-Based Authorization (RBA), the access permissions are granted to a role rather than assigning them directly to a user/client. There could be multiple roles having different permission levels and a user will get assigned one or more roles. Once a user is authenticated, the permissions are retrieved based on the role(s) assigned to the user. RBA simplifies the access control and managing the roles easily when compared to the Attribute-Based Authorization. The advantage of this approach is, instead of updating access of users individually, we only need to update the role to control the access of multiple users at once.

Attribute-Based Authorization

In Attribute-Based Authorization (ABA), the access permissions are granted based on the attributes that are associated with the user. This depends on the resources or actions to be accessed and also the context associated with the request. This provides a fine-grained access control to the user rather than the role based authorization.

Future of Authentication and Authorization

With the advancement of technology, new mechanisms for Authentication and Authorization may emerge. These could range from improvements in multi-factor authentication and biometrics to areas we have not yet imagined. Additionally, as technology, especially in areas like quantum computing, continues to develop, new types of threats may arise daily. Thus, applications should be adequately protected against these emerging threats, and we must remain proactive in identifying potential future challenges.

API Design-First with Authentication and Authorization

API Design-First (also known as API-first design or API-driven development) is the approach for designing the API specification before writing the code for actual implementation. Adhering to API-driven development gives us a lot of advantages.

  • Clear API Contracts: The APIs that need proper authentication and authorization can be identified in advance. There could be some APIs that can be accessed by any one (public) and some APIs could be accessed only by those who have admin privileges. Identifying and defining these contracts will help for solid implementation and validating the implementation against the specification.
  • Compliance: APIs are subject to regulatory requirements, such as GDPR and HIPAA. Starting with a security-focused design ensures that the APIs comply with security and privacy standards.
  • Testing: API design-first includes API mocking and testing, which can be used by developers verify that proper authentication and authorization mechanisms are in place.

There are different tools that can be used for implementing the API Contract (API Specification) in API Design-First approach for authentication and authorization. Xapi is such a great tool fully compliant with Open API Specification 3.1.0 and can be used to achieve design specification and testing.

Summary

Authentication and Authorization are among the most critical areas to address when safeguarding data manipulated through APIs. Protection for the APIs and data should be continuously updated to defend against the emerging threats that arise daily.




Author

SB Karunarathne

Technical Lead | X-Venture