The importance of secure authentication in modern applications has grown exponentially in the last decade and continues to rise. The security of your personal information, private messages, photos, contacts, bank transactions, and much more is at stake whenever you use any online service. While some corporations build their income on top of security, the vast majority of companies, regardless of size, are susceptible to cyber threats, as demonstrated by the recent increase in data breaches.
In this series of articles, I will cover various approaches to storing users' credentials and create a small, yet secure, application to demonstrate them. Rather than targeting a general audience, these articles are aimed at architects and developers, for whom they will be exceptionally useful.
The technology stack I've chosen is fairly standard – PostgreSQL, Java with Spring, and Angular. While these technologies are popular, the concepts and approaches discussed in the series can apply to any modern stack.
Key Concepts
Before we move on, let's refresh some key knowledge:
Authentication is the process of verifying the identity of a user or system. For example, when a user signs in, the system checks if the credentials are correct.
Authorization, on the other hand, is the process of determining the user's or system's permissions. For example, a signed-in user might be able to view and edit their own data if they're a "regular" user, or edit anyone's data if they have "elevated" permissions.
While these processes are often discussed together, they're distinct and entirely different, although interconnected. To use an analogy, if this were a concert, authentication would be the validation of your ticket, and authorization would be moving to your assigned seating zone.
The Role of Authentication & Authorization
Setting aside intentional data leaks, where someone with access to user data "dumps" or exports it, the majority of breaches occur due to poor authentication or authorization practices, whether it's weak password policies, outdated cryptographic algorithms, or what's commonly called "Broken Access Control".
To mitigate some of these vulnerabilities, weak passwords can be addressed by implementing Multi-Factor Authentication (MFA), also known as the "six-digit code from an email or app," which can be easily integrated into systems of any size.
Commonly used authorization models include:
- Role-Based Access Control (RBAC): Pre-defined user roles and their access scope.
- Attribute-Based Access Control (ABAC): Access is granted based on various attributes such as device type, user group, or file type.
- Discretionary Access Control (DAC): Provides granular permissions with flexibility in exchange for increased complexity.
Modern Approaches
One of today's techniques to secure authentication and minimize data leakages is using advanced hashing algorithms like bcrypt and Argon2 for secure password storage and to prevent brute force attacks. These algorithms are computationally intensive, requiring a substantial amount of power to encrypt passwords, but also making brute force attacks against the resulting hashes extremely difficult – potentially taking days or even years to decrypt a single password with cutting-edge technologies.
As mentioned earlier, MFA mitigates the risks of weak cryptography by requiring users to provide a "second factor" for signing in. The first factor is something the user knows – their password. The second factor is something they possess, such as a trusted device, a smartphone with an app, or a secure token. But we'll get to that later in the series.
Improved Approach
Server-side password hashing is good enough to protect user accounts in case the database gets leaked, but we can enhance security tenfold by implementing the zero-knowledge approach. This improvement is why our app will be called "Knox."
Series Roadmap
In the following articles, I will describe in detail and implement:
- Database design to store and manage user accounts
- Classic approach to password storage
- Frontend application (because an API alone won't cut it)
- RBAC with Spring
- Improved approach to password storage
After we've laid the groundwork, we'll dive into more advanced topics like:
- MFA, with proper time-based implementation
- WebAuthn, for a cutting-edge authentication flow
- OAuth2, to implicitly sign users up
By following the series, you'll not only gain a fully functional backend with a GitHub repository included but also priceless knowledge. As a bonus, you'll have a neatly designed frontend with a wonderful user experience, crafted especially for this series by a friend of mine Andrii.
Cover image by Kai Pilger on Unsplash
Top comments (0)