Authentication systems are the protective barrier of any software. It makes sure that right people enters the system and access the right information.
Though being the major component of an application, the chances of you building one from the scratch in the industries less, Unless you are working on a project from scratch. That being said, the most common advice in a hackathon is to not waste time implementing login page. Now as years go by and as you grow up the career ladder, it is important to understand how the whole system works to elevate yourself as an architect and make more educated design decisions.
When thinking about authentication, the common imagery people have is a login HTML page submitting data to a backend API cross checking it with a data in a DB? Well, though it covers the bare bones of an authentication system. There is more to it which we would discuss in the rest of the blog.
- Types of Authentication
- Digest Based Authentication
- Cookie/Session Based
- Token Based
- Two Factor Authentication
- Access Control
- Types Of Access Control
- Which authentication method to use?
- Designing a distributed auth system
Before we move on…
All data sent to clients over public links should be considered “tainted” and all input should be rigorously checked. SSL will not solve problems of authentication nor will it protect data once it has reached the client. Consider all input hostile until proven otherwise and code accordingly.
It is the simplest of authentication mechanisms. It is a part of HTTP protocol. It is a challenge response scheme where the server challenges the client to provide necessary information to access the resource
- Get the username and password from user
- Encode it using
- Set it in the Authorization header and send it along each HTTP Request.
`Authorization: Basic XAAUVBBhHI87IO==`
- Easy and simple to implement
- APIs are faster since there is no complex encryption/decryption involved
- Basic Auth implemented in a non-SSL (HTTPS) network is a huge security vulnerability.It is easy to decode an Base64 string since it is an universally known algorithm
- HTTP is stateless that means you need to send the auth headers along with every HTTP request which is an overhead when designing a huge application
- Sending passwords over all the HTTP request provides a pool of requests for attackers to pick passwords from. Once they crack one the system becomes open for attacks.
It is an upgraded version of Basic auth. It overcomes the security vulnerabilities of Basic auth over an HTTP network. We no longer deal with
base64 encoded strings, instead the server provides digest for the client to use while encoding the username and password. In digest base auth we no longer have to worry about universally known base64 encoded string.
Note: This doesn’t mean it is ok to send passwords over non-HTTP network, it provides just a safety net if you do so.
- Request a server for a resource with no auth
- Server sets the header with certain digest information
- Get the username and password from user
- Hash the username and password along with the digest send it to the server.
- Server decodes the string with the digest and allows the user
- Prevents passwords sent as plain-texts
- Avoids Phisiing
- Digest method is still vulnerable to man in the middle attacks.
- Client has to make 2 calls to get a resource, one to get digest information and another to login
Cookie/Session based authentication is the most commonly used in web apps. Yes, both session and cookie are not exactly the same but the conceptually either the client uses a cookie/session to identify itself as a logged in.
- Get the username and password from user
- Set it in request form params and send it to the server
- Server validates the user based on the given username and password
- Once successful validation, create a cookie and set it in the response
- The client then uses this cookie/session to make future requests.
- We no longer set the password in every request making the window for attacks smaller.
- Enables state maintenance in a stateless system. Cookies maintain the state that the user is already logged in.
- Can revoke the validity of a cookie anytime.
- Cookie based authentication is suitable only for Single domain system. If you want both a web and a mobile app or may be a separate client server, then you got to deal with CSRF.
- Prone to XSS and CSRF attacks since the cookie is available for other apps to read
- You need to store the session information in a DB which also brings in the question of scale
Token Based Authentication is a form of stateless authentication. Instead of sending email and password over for authentication we use a server generated token. Oauth, JWT, Open ID all comes under token based authentication
- User submits a username and password
- Server validates and returns a singed token JWT
- Use the token to allow future requests
- The server no longer have to bear the overhead of session information
- No more CSRF. With token based auth you are dealing with a bunch of APIs consumed by different clients
- Works well on microservices architecture.
- Cannot revoke the access to a user.
- The safety of the token relies on the consumer of the token.
Oauth2 is an advanced version of Token based authorization. Often we use Facebook/Google/Twitter to sign-in to an application. These are the examples of OAuth2.
- User sends an authentication request to say Google/Facebook.
- On finding that the user has an account on Google, the Google server responds with an authorization grant.
- The requesting application uses the authorization grant access specific information
- On gaining the permission, the app generates an access token.
- The client then uses the access token to access a resource.
Personal computers are classic examples of an SSO system i.e., you enter password once and get access to all the apps. Google is another classic example you login to Gmail and get to use all the GDrive apps that comes along with it.
- Let’s say you are trying to access Google forms. Google sends a request to the forms, the forms of service inturns calls an authentication service to make sure that the current user is logged in
- if the person is already logged in present with the information
- If not show him a login screen to authenticate the user.
This sounds similar to oauth but, the major difference is Oauth allows only specific access to an app whereas SSO provides complete access of the data available
- Talk about user experience your user needs to remember only one set of password
- Secure, since a single service is holding your password and is responsible for its security
- Single point of failure: When an authentication service goes down all the app relying on it cannot be accessed
- Any security breach in the authentication system will open access to a wide set of apps and data.
Two Factor authentication is a subset of multi-factor authentication. There are 5 broad classification of these factors
- Knowledge Factors - Which city are your from?
- Possession - OTP, Validation email
- Inherent factor - finger print, eye ball scan
- Location Factor - GPay
- Time Factor - When system is allowed to access only at a specific time
Authorization is something that happens once the user logs into the system. Does an user have access to a specific information? For example, in a library the lenders need not know the billing/vendor information related to each book. In a system that involves more than one type of stakeholders, the authorization is as important of authentication.
Authorization is achieved using access control, you can imagine it as a “Restricted Area” sign with a guard.
- RBAC - Role Based Access Control - A user with specific roles can access specific data.
- MAC - Mandatory Access Control - High security systems avail these kinds of access control
- DBAC - Discretionary Access Control - The business data decides which information is available for a specific user. E.g., A library lender can only see books lent by themselves.
- Only Web Application - Cookie/Session Based
- Expose APIs to user - Token Based
- Web + Mobile Apps - Cookie and Token Based
- Letting users login easily Oauth
- Building apps on top of Google/Facebook - SSO
In a monolithic application the authentication APIs are tightly coupled to the app itself I.e., we will have a single DB storing both the user information and the business data. In that case there is a single instance of a server responsible for authentication.
In a distributed system with microservices architecture the design becomes a bit more complicated.
Answering the following questions and understanding its pros and cons will help us land in an educated decision
Microservices architecture directly translates to independent services working together with that ideology in mind “Auth inside every microservice” looks like an anti-pattern. Though an advantage of this method is reduced latency, we would end up doing a bunch of redundant things at every server.
If that’s the case with having auth service at each end and the auth system validates each request like a firewall. The drawback of this method is that auth service itself will become a bottleneck as the number of requests scales up.
The most commonly practiced method in microservice architecture where the authentication system sets a JWT token to the client and any request that made to the services are then cross verified with the Global system.