1.7. Authentication in web applications


Authentication vs. Authorization

You've probably heard the words "authentication" and "authorization" quite often. What do they mean, and what's the difference between them?

In simpler terms, authentication answers the question, "Who are you?"

Authorization, on the other hand, answers the question, "What can you do?"

Let's consider a simple example. Imagine we have a web application where users can publish, edit, and delete articles. However, only users who are registered in the system can perform these actions. Therefore, when a user wants to take a specific action, they need to go through a special process that allows the system to recognize and identify them, i.e., authenticate.

In the system, all users are divided into groups with specific access rights, such as "User" and "Admin." Users in the "User" group can publish, edit, and delete their own articles. However, these users do not have access to articles from other users, even if they belong to the same group, which means they cannot edit or delete other users' articles.

Users belonging to the "Admin" group can perform any actions on all users' articles. After successful authentication, the system determines which group the user belongs to and what access rights they have and what actions they can do, which is the process of authorization.

There are several methods and protocols for authentication. In this article, we'll explore the most popular ones:

  • HTTP Authentication
  • Certificate-Based Authentication
  • HTML Form-Based Authentication
  • Single Sign-On (SSO)


Basic HTTP Authentication

Basic HTTP Authentication is defined by the HTTP protocol itself, making it a "native method." The working principle is illustrated in the diagram below:

Principles of Basic HTTP Authentication

  1. The user accesses a website or a restricted section of a website where authentication is required.
  2. The server responds with a 401 Authorization Required status code and adds the WWW-Authenticate header. This header contains the authentication type (Basic) and the Realm field, which represents the name of the closed section to which access is requested.
  3. When the browser receives such a response, a simple window pops up at the top of the browser for entering authentication data.
  4. After entering the username and password, the browser combines them into a single string, separating them with a colon, like this: login:password. It then encodes this sequence using the Base64 algorithm.
  5. Afterward, the browser sends the same request as in step 1, but in this case, it adds the Authorization header, containing the encoded sequence.
  6. Upon receiving the request, the server decodes the Authorization header value and extracts the username and password. If they match those in its database, the server responds with a 200 OK and grants access to the requested resource.

Basic HTTP Authentication has its drawbacks:

  • The browser needs to transmit authentication data with each request.
  • The password is transmitted openly over the network, requiring an SSL/TLS connection for security.
  • There's no option to "log out" of the application. The only way out is to enter an incorrect password or username.


Digest HTTP Authentication

To enhance the security of the previous method, the Basic Authentication mechanism was improved and named Digest Authentication. Its distinctive feature is that the password is no longer transmitted over the network. Instead, a unique sequence known to both the browser and the server is computed. The working principle is shown below:

Principles of Digest HTTP Authentication

  1. The user accesses a website or a restricted section of a website where authentication is required.
  2. The server responds with a 401 Authorization Required status code and adds the WWW-Authenticate header. This header contains the authentication type (Digest), Realm field, and other data.
  3. When the user enters their data, the browser combines them into a single string and then computes a hash. Typically, MD5 serves as the hash function.
  4. Next, the calculated hash and additional information are sent in the Authorization header.
  5. The server performs the same calculations, and if both hash values match, the user is authenticated.

It was a simplified scheme. A slightly more complex version involves the use of the Nonce parameter - a unique random sequence that also participates in hash computation. The issue with a fixed hash value is that if a hacker intercepts it, they can simply use the computed hash for authorization on the site without knowing the actual password.

To avoid this situation, the server generates a random sequence with each request and sends it as the Nonce parameter. This sequence is added to the authentication data, and then the hash is computed. As a result, you get a constantly changing hash.

As you can see, the password is not transmitted over the network at all. However, it's not entirely secure to call this method the safest either. Basic authentication and Digest authentication are hardly used nowadays.


Certificate-based Authentication

When connecting via SSL/TLS, browsers verify the certificates installed on websites to authenticate servers (more details here). Similar certificates can be installed on computers, allowing servers to authenticate users (or devices) connecting to them. In turn, the server contains a list of certificates and users authorized to connect to it.

This method is quite reliable (although both certificates and authentication centers can also be compromised), but it has significant drawbacks:

  • Providing many users with necessary certificates is quite complex. Therefore, this method is mainly used on government websites and only for a small number of users.
  • The certificate is installed on a device (computer, laptop), meaning you can access the website only from a specific device. It can also be installed on a flash drive, but this is not always convenient.


Form-Based Authentication

This method is based on the use of various HTML forms containing fields for entering a username and password. The entire process is illustrated in the image below:

Form-based authentication with Cookie exchange

Form-based authentication with Cookie exchange

  1. The user requests a specific resource on the website, such as wanting to access a confidential document.
  2. The server redirects them to the login page, which contains an HTML form for entering user credentials.
  3. After entering the data, the browser sends it to the server via a POST request, with the data sent in the request body as parameters in the format parameter_1=value_1&parameter_2=value_2. The parameters are separated by ampersands. Here, there is a similarity with Basic Authentication, as both methods use a form and transmit data in plain text. Thus, it's essential to always use an SSL/TLS connection.
  4. Upon receiving the data, the server compares it with the information stored in the database. Storing passwords in plain text in the database is not recommended, as a compromised database could expose all passwords. Therefore, instead of passwords, password hashes are stored.
  5. If the passwords or their hashes match, the server generates a new session identifier and sends it via the Set-Cookie header. It's crucial to set attributes such as HttpOnly (to prevent cookies from being accessible to JavaScript), Secure (to ensure cookies are transmitted only over SSL/TLS) and Expired (to have browsers and servers automatically delete cookies after a set period).
  6. The browser accepts and stores the cookies for subsequent transmission to the server.
  7. The authenticated user requests access to the confidential document again. The browser automatically adds the cookie to each request.
  8. The server checks and compares the received cookie value with the value stored in its storage or database. If everything is correct, the requested resource is provided to the user. Notably, the user doesn't need to repeatedly enter the password.
  9. If the user wishes to log out of the system, they send an appropriate request.
  10. The server deletes the current cookie value and generates a new value, which is sent via the Set-Cookie header.
  11. Upon accepting the new cookie value, the browser deletes the old value and stores the new one.

This method is widely used in many web applications; however, it's not without drawbacks, as it's susceptible to SQL Injection (SQLi) and password attacks (Brute force, Dictionary attack, etc.). Therefore, on the server side, careful validation and checking of the entered data are necessary. This applies to all web applications and authentication methods that involve transmitting user data and parameters.


Single Sign-On (SSO)

Single Sign-On (SSO) is a technology that allows users to access multiple web applications using a single set of credentials. Instead of entering a username and password for each application individually, the user can log in once and automatically gain access to all their applications. For example, you've probably encountered applications that offer sign-in options using Google or Facebook accounts.

The principle behind SSO involves using centralized authentication, which verifies the user's identity and passes authentication data to applications when needed. In such a system, each application doesn't store user passwords but accesses the user's account through the authentication server.

During the authentication/authorization process, at least three parties are involved, so let's start by defining the terminology.

Service Provider (SP) or Client: This is the web application that requests access to your data or resources. For example, it could be Spotify, which, for user authentication, might request resources from Google or Facebook:

Example of SSO authentication

Identity Provider (IdP): The Identity Provider is an authentication server that stores your credentials as well as your resources. These resources can include photos, documents, media files, and more. Google, Facebook, VK, and many others can serve as IdPs.

User-Agent: This term refers to the actual user. In various sources, it can be referred to as Client, User-Agent, or simply the browser.

The SSO process is illustrated below:

SSO Authentication flow explanation

  1. In the beginning, the Service Provider (SP) and Identity Provider (IdP) establish trust relationships with each other. In simpler terms, the SP registers with the IdP to use its users' credentials on its own website.
  2. Then, the user requests access to the services of the Service Provider (let's say it's Spotify).
  3. The Service Provider first asks the user to authenticate, for example, with Google. To do this, it redirects the user to Google's login page, including its own identifier and many other parameters in the URL request.
  4. The Identity Provider, in our case, Google, prompts the user to enter their username and password.
  5. After successful authentication, the IdP generates a special token containing information about its expiration, a digital signature, and other data. This token is sent back to the SP through the user's browser using a redirection request.
  6. The Service Provider receives the token, verifies its digital signature to ensure it's not counterfeit, and then provides the user with the requested resources, such as access to a restricted part of the website. The token is stored in the user's browser, and for subsequent requests to the Service Provider, the browser sends the token either in the Cookie header or in the body of a POST request.

The above-described process is abstract, as in reality, there can be more or fewer intermediate steps depending on the protocol implementation, web applications, and user-agent.

To implement Single Sign-On (SSO), the following protocols are used:

  • OAuth 2.0
  • OpenID Connect (OIDC)
  • Security Assertion Markup Language (SAML)

The following technologies are used to implement tokens:

  • Simple Web Token (SWT)
  • JSON Web Token (JWT)
  • Security Assertion Markup Language (SAML)

OAuth 2.0 and OpenID Connect are often used together since OAuth 2.0 is used only for authorization (for example, the IdP grants the Service Provider permission to access the user's resources). These resources could be files, such as photos or a contact list. OAuth does not authenticate the user, so OIDC is implemented on top of it, which handles the authentication process. As a result of successful authentication and authorization, the IdP generates two tokens: an access token and an identity token. Typically, the JWT format is used for token generation.

SAML performs the same functions as OAuth and OIDC, providing both authentication and authorization. However, it uses XML messages. It is more complex in its implementation and cannot be used in mobile applications.