Access control
Access control includes the activities of registration, authentication and authorization of users.
Registration
The user register is associated with the storage of that information necessary to be able to authenticate them later. It is important to avoid leaving information in the clear in files or databases, to save us security problems. Also, avoid encrypting passwords.
A common scheme is to use digests or hash. If we save the hash in the DBDD, we won't know what the password is, but we can compare what the user enters with the saved hash, and say if it's the same.
This has only one problem: there are pre-built tables to look up hash-to-password correspondences. This forces us to add a random string (jump) next to the password, and then the hash of everything is not always the same for the same password. This hop doesn't have to be private, it serves the purpose of making common password cracking tactics useless, and can therefore be kept in the clear in the DBDD.
When doing the authentication we will only have to make the comparison between the hash stored and the calculated one:
Is hash(salt + password1) equal to hash(salt + password2)?
Authentication
Authentication usually involves collecting the identification of the user in order to verify their authenticity.
Once we have the authenticated user, he can receive an identifier generated by the server and that the client will have to send each request to the server in order to confirm that he is authenticated.
The client / server applications can be differentiated into two types: stateful and stateless: with and without state. This refers to whether or not the server stores data associated with the authenticated user, which is called a session.
- Stateful: with session and data stored on the server. The identifier generated is that of the session. The server passes an ID to the client, which it uses every time it communicates with the server. The server uses it to get the data associated with it.
- Stateless: No session and data stored in the client. The generated identifier is called token. It can simply be a generated ID, or it can contain cryptographically signed information.
Identifier in the client
In web applications, if a client is authenticated it needs to let the server know using some sort of secret identifier. The client could be a browser, if it is a user web application, or a client application.
If the client is a browser, there are basically two schemes for saving this identifier on the client: cookies and web storage.
- cookies are part of the HTTP protocol. They allow name/value cookies to be saved via a "Set-Cookie" header from the server (response), and inform the server of current cookies via a "Cookie" header from the browser.
- The web storage is a mechanism that can be activated from the client exclusively, through scripting. We have two objects, sessionStorage and localStorage, that allow setItem/getItem type actions on name/value pairs. It is not a mechanism that directly replaces cookies, despite being similar.
Both of these technologies could store credentials to access applications. Cookies send the information directly to the server, while web storage allows the client to manage the information exclusively.
If it is a client application, this information can be saved by the corresponding software, and sent when needed to the server.
In the event that the identifier is not encrypted, it is important that it is not easily deduced to prevent malicious construction (random and long ID). JWT provides the option to encrypt access and authorization information.
Sending the identifier
Some possible methods for sending the identifier to the server are discussed below.
HTTP Basic Authentication uses a header of the type:
Authorization: Basic base64(username:password)
cookies are the most classic method, and allow two special headers, one from the server:
Set-Cookie: sessionId=shakiaNg0Leechiequaifuo6Hoochoh; path=/; Safe; HttpOnly; SameSite
and another from the client:
Cookie: sessionId=shakiaNg0Leechiequaifuo6Hoochoh
The tokens (bearer) are passed using a header:
Authorization: Bearer ujoomieHe2ZahC5b
Tokens usually have a validity limit, and are often used with stateless applications.
The signatures (signatures) sign and send the significant data of the request in form format. For example: AWS API.
TLS client certificates perform a handshake before any HTTP request.
Multi-factor authentication
Authentication can be based on something the user knows, has, or is. We can have a single authentication factor, or combine them. It is common to have two-factor authentication in more secure services.
A second common factor is the One-Time Password (OTP). They can be based on time synchronization or mathematical algorithms that generate strings. There are two implementations: HOTP (HMAC) and TOTP (Time). The difference is what they share to generate the password: a counter or time (Google Authenticator).
- The server creates a secret key for the user, and shares it with a QR code (it's long).
- Both parties will generate the OTP, and the server will have to validate if it is the expected one.
The generation is done with this formula:
- hash (shared secret + counter) = HOTP
- hash (shared secret + time) = TOTP
Authorization
Once the user has been authenticated, there are a number of permissions that are assigned to them based on their role within the application. There are different ways to assign them:
- Level: Users and tasks have levels, a user can do tasks with a level equal to or lower than their own.
- User: user-task pairs are made (many2many)
- Group: A user has a group, group-task pairs are made
- Responsibility: A user can have multiple groups
Once permissions are assigned, it is important to make them effective in each of the user's interactions with the system. This can be done both stateless (example: authorizations inside JWT) and stateful (storage in server session).