Authentication Strategies for Modern Web Applications

Authentication Strategies for Modern Web Applications

Jul 18, 2023

Authentication and authorization are crucial aspects of modern web applications. Authentication ensures that the user is valid and verifies the user's identity while authorization determines user permission and access level. Authorisation is performed after successful user authentication so that they can access specified resources in the web application.

There are different ways how a web application can perform authentication and authorization. In this blog post, we will look at 4 standard authentication approaches used in most of the web applications made today.

Session Authentication

Session authentication is a simple and common approach used in many web applications today. It relies on a session ID that is shared between the client and server to maintain user state.

When a user logs in with valid credentials, the server generates a unique session ID which it stores in a database or memory. The session ID is sent back to the client as a cookie. On subsequent requests, the client sends back the cookie containing the same session ID. The server validates the ID against the stored sessions to authenticate the user.

The main advantage of session authentication is it is straightforward to implement in most web frameworks like Laravel and Django. The session state stored on the server also allows easy access to user data across requests.

However, storing sessions on the server can have scalability and cost issues for large user bases. The server memory and bandwidth for session storage grow as more users are added. This makes session authentication less ideal for public-facing sites and apps with millions of users.

JWT Authentication

JSON Web Tokens (JWT) have emerged as a popular authentication strategy, especially for Single Page Applications (SPAs). JWTs help fix scalability issues faced by session-based authentication.

Similar to session-based authentication, in JWT authentication, when a user logs in, the server generates two tokens - an Access Token and a Refresh Token. The Access Token is short-lived and can contain public user information like email and user ID. It is stored client-side in the browser's local storage. The Refresh Token has a longer expiry and is stored in an HTTP-only cookie. We can talk about HTTP Only Cookie in the next blog post but for now, remember it as a special type of cookie that cannot be accessed from the browser itself and needs an HTTP communication to access it.

Both the Access Token and Refresh Token are signed by the server using a private key, but they do not need to be stored in a database. The private key used for signing is kept securely on the server, often as an environment variable. On each request, the client sends the Access Token in the HTTP header. The server validates the token signature against the private key and retrieves the user information encoded in it. When the Access Token expires, the Refresh Token can be used to renew it without re-authenticating the user. This renewal process validates the Refresh Token signature before issuing a fresh Access Token. The private key on the server provides the cryptographic mechanism to verify tokens issued by the authentication system.

Storing the Refresh Token in an HTTP-only cookie provides additional security. Even if the Access Token is compromised from the client, the Refresh Token remains protected from cross-site scripting attacks. The two-token approach balances security and performance for efficient authentication in SPAs.

OAuth 2.0

If you have seen "Sign in with Google" or "Log in with Github" or any third-party site in a modern application today, then they all rely on OAuth2.0 for secure third-party authentication and authorization. OAuth provides delegated authorization for users through third-party services. Instead of managing passwords, users log in via their Google, Facebook, GitHub accounts, etc. which then provide limited access tokens to the application.

For example, say you want to sign up for a new app using your Google account. When you click "Sign in with Google", you are redirected to Google's login page. After entering your Google credentials, Google prompts you to authorize access to basic profile info like your name and email address. Once you approve, Google sends an access token to the app via a callback URL. The app can use this token to call Google's API and get your public profile information. It links your Google identity to a user account without ever handling your Google password. You avoid creating new credentials, and the app never stores your actual Google credentials.

This delegated authorization is at the heart of OAuth 2.0. Services like Google, Microsoft, and GitHub act as external identity providers. They authenticate users and provide access tokens with limited scopes to third-party apps. Users can easily revoke app access if needed. OAuth enables secure single sign-on across services without exposing passwords.

Single Sign-On (SSO)

Single Sign-On or simply SSO is an authentication system for users to access multiple applications with one set of login credentials. It is similar to how a user logs in with Google to authenticate with an app but SSO is commonly used by an organization that relies on many different third-party software tools.

For example, a company may use Microsoft Outlook for email, Calendly for scheduling, Zoom for video calls, a VPN client, and other SaaS apps. Without SSO, employees would need separate usernames and passwords for each one. This leads to password fatigue and reduced productivity.

SSO provides a single authenticated gateway to all the organization's applications. An employee logs into the SSO portal using their work credentials. From this dashboard, they can seamlessly launch and access all their approved enterprise apps without re-entering credentials.

Behind the scenes, the SSO provider handles authentication and authorization by securely passing the user's identity to each application. This creates a unified access experience for employees. They can easily switch between different apps and tools without constant authentication. SSO increases convenience and improves security. Employees have fewer passwords to remember and change regularly. The organization can also manage access and authorization centrally through the SSO provider.

At its core, SSO uses standards like SAML, OpenID Connect, and OAuth for secure communication and validation between identity providers and applications. While Single Sign-On (SSO) creates a seamless access experience for users, there are several steps happening behind the scenes to securely pass identities between applications.

When a user attempts to access an application like Zoom that is connected to their organization's SSO, the following happens:

  1. The user's browser makes a request to the Zoom login page.

  2. Zoom detects this is an SSO login and returns an authentication request back to the browser. This authentication request is a signed SAML, OAuth, or OpenID Connect message.

  3. The browser passes this request on to the organization's identity provider. The identity provider manages all user identities and access policies centrally. Okta and OAuth0 are some examples of commonly used identity providers.

  4. The identity provider validates the user's session and generates an encrypted assertion or signature confirming their identity.

  5. This assertion is sent back to the browser, then passed on to Zoom.

  6. Zoom validates the signature on the assertion against the identity provider's public keys.

  7. If valid, Zoom logs the user in and establishes a local session. No credentials are exchanged.

This behind-the-scenes circle of trust allows the identity provider to securely pass the user's identity to Zoom and other SSO-enabled apps. The user simply clicks and immediately gains access without reauthenticating. SSO standards make this happen seamlessly.

Conclusion

User authentication is a crucial aspect of securing access in modern web and mobile applications. In this article, we discussed four different authentication strategies and how they work.

Session authentication provides simplicity but lacks scalability. JWT token authentication is stateless and scalable. OAuth 2.0 delegates authentication to trusted external providers for single sign-on. And SSO systems take this a step further by centralizing access control across all an organization's applications.

The right authentication approach depends on the specific use case and requirements. Applications with limited users may benefit from traditional sessions, while consumer apps and Single Page Applications need a JWT approach that scales. SSO delivers convenience for enterprise scenarios with many integrated SaaS tools. There are tradeoffs wherever we look. By understanding and analyzing the requirements and the tradeoffs, we should seek for the right balance between user experience, infrastructure needs, and application security. Authentication may not be the most exciting topic, but it's one of the foundations for building robust and scalable applications.

If you found this information useful, please consider sharing it with friends or colleagues who may also benefit from it. If you have any questions or would like to discuss the topic further, you can reach out to me on Twitter at https://twitter.com/aabiscodes or LinkedIn at https://www.linkedin.com/in/aabis7/.