Modern Authentication is typically not a single solution, but a set of modern, universally accepted standards and protocols that identify industry best practices.
These standards include protocols such as Security Assertion Markup Language (SAML), Web Services Federation (WS-Federation or WS-Fed), OAuth 2.0, or Open ID Connect (OIDC). These protocols and standards have replaced legacy authentication models that are seen as less secure. For the purposes of this blog, the primary focus will be on OAuth 2.0 and OIDC – each of which is discussed in detail below.
In addition to a shift from legacy to modern authentication models, there is adoption of a “Zero-Trust” model. This model has been developed to manage the paradigm of distributed workforce – incorporating a growing cloud adoption and a growing number of remote workers. This model is discussed in detail in the below section.
This provides a perspective of the “ideal state” of authentication models – simply to lay the framework that existing state(s) can be compared against. As with any ideal state, it is not expected that every component or element is adhered exactly to, or fully implemented.
Throughout this documentation of modern authentication, there may be references to specific technologies (e.g., Microsoft, Okta) that utilize these specifications. The intent of this document is not to advocate for or prefer one technology over another – instead it provides a concrete example of an open standard. As modern authentication is defined as a set of open standards, the ability of an implementing entity to switch IdPs should be near frictionless.
Finally, this is not meant to be a comprehensive guide to all details of modern authentication. Instead, it should set the foundational groundwork of what modern authentication is and its core components.
The OAuth 2.0 specification utilizes a series of flows to implement trust and identity validation. These flows each have a different purpose and are designed to create a normalized approach to management of systems. The default flow – the Authorization Code Flow – is designed in such a way that a trusted application can validate both the user credentials and its own credentials to act on behalf of a user. This process starts with a request for identity from an IdP, asking the user to validate themselves. This process may utilize a one or more pieces of information from the user, such as something they know (password, security question), something they have (SMS, email), or something they are (biometrics). Once this identity has been satisfied, the IdP will return an authorization code to the web application. The web application then sends this code and its credentials back to the IdP to obtain a token – in the form of a JWT – that can be used for subsequent requests. In the case of the below diagram, Okta acts as the IdP – but the flow is the same for any provider implementing the Authorization Code Flow specification.
Figure 1: Okta Authorization Code Flow (source)
Proof Key for Code Exchange (PKCE) is a process that involves generating a unique key for every authorization request. This helps ensure that the provided authorization code matches the original web app request. By generating a code then hashing the code, the hashed value can be sent to the Authorization Server with the original Authorization Code Request. When the Client (as opposed to Web App) now requests the code with the provided authorization code, it can send the clear (not hashed) value of that key, which the Authorization Server can then hash and verify the request.
Figure 2: Okta Authorization Code Flow with PKCE (source)
Figure 3: Microsoft Client Credentials Flow (source)
The Implicit Flow – which should be avoided unless necessary as the confidentiality of the client secret cannot be guaranteed. This flow typically does not support any form of refresh token and is designed for legacy browsers that do not support modern cryptography.
While different IdPs may implement additional flows for special purpose solutions, the flows documented here should provide a good basis for understanding of the OAuth 2.0 structures. As part of some flows, an optional refresh token can be requested and provided. Refresh tokens can be sent to the /token endpoint directly, along with client information to obtain a new token. This allows a user to recreate or maintain a session without being prompted for validation again. Refresh tokens should be treated like passwords, as they allow an application to act on behalf of a validated user.
Figure 4: OAuth Flow Decision Tree (source)
An IdP will implement two primary endpoints: /authorize and /token. The /authorize endpoint will be responsible for validating the user identity and minting an authorization code. The /token endpoint will take an authorization code and client credentials (credentials provided to the web app or client app by the IdP) for validation. If valid credentials are provided, then the /token endpoint will mint a JWT that can be provided back to the web or client application for use in the Authorization header. This token is a “Bearer” token, as defined in the Authorization specification.
When requesting an authorization code from the /authorize endpoint, the OAuth specification includes as part of the request a list of scopes that the user must consent to. These scopes are basically the authorization components of the web or client application. Depending on the IdP configuration, the user may have to interact with a dialog to consent to one or more of these scopes, so the authorization code can be provided.
OpenID Connect (OIDC)
OIDC is built on top of OAuth 2.0 and is designed to extend the functionality of OAuth with a second token call the “id token.” Some of the scope models are standardized in the OIDC specification, but the primary purpose of OIDC is to enable federated identity that contains core information about the user. The best way to think about OIDC is the “Login with Facebook” or “Login with Google” button that might be displayed on a website. When this button is selected, the web or client app will send a request to the respective IdP, and when the user establishes a session with that IdP (if they do not already have one) they will be prompted to allow the client or web app to access information, such as email address, name, address, etc. When these requests are granted, the IdP (Facebook or Google) will send the authorization code back to the application, just as with normal flows. When the app sends the request to the /tokenendpoint, they are presented with both the access token and the id token. The access token is used with the Authorization header as the Bearer token, while the id token contains claims that the IdP validates are true about the user, such as name, email, or other information.
It is important to understand that support for OIDC is in addition to OAuth2.0, not exclusive of it. Whenever this document references modern authentication, it will refer to the combined support of OAuth 2.0 and OIDC models.
Zero Trust Architecture
Zero Trust or Zero Trust Architecture is a modern paradigm to handle cybersecurity in the modern technical landscape. Rather than identifying more static, network-bound (network based) perimeters, it focuses on a more granular set of assets and users. This model simply states that there is no implicit trust granted based solely on a physical or network location or ownership.
Legacy trust architectures can be compared to a castle. The castle has high walls, a moat, and limited entry points – however once access to the castle is achieved, there is no validation, verification, or checks that access should be granted. This represents a corporate intranet, where resources may have minimal or no security – instead rely on network perimeters to validate access. Modern Zero Trust Architectures are much more like gated communities. The community, as with the corporate network, has controlled entry points and checks, however, access to each house within the community also requires appropriate access, controls, and checks. In a Zero Trust Architecture, each application – acting as a Service Provider – requires that correct credentials (access token) be presented in before access is granted.
This model is designed for the modern world of applications and work – one where Software as a Service is prevalent and cloud integrations are common. It is especially important in the modern workforce, where remote workers are normal, and corporate VPNs and connections are not sufficient to prevent breaches. One of the most common breach patterns – called Privilege Escalation – hackers utilize is to obtain credentials from a user, and then parallel inside of the intranet, until they can obtain more privileged credentials. This process is repeated until they have reached the interior of the network perimeter and can access network and corporate resources. Zero Trust Architecture, along with least-privilege models – are meant to help reduce or limit the attack surface.
To better understand this, the following analogy has been provided. It is by no means perfect, but it should be help build mental models for modern authentication.
Imagine the case of a Driver’s License in the U.S. The license is controlled by the state and issued by the controlling entity. In the case of a license or even an ID card, the state is acting as an IdP – establishing the identity of the bearer. When a license is then presented to another Service Provider – say a restaurant – there is an implicit trust between the state and the restaurant that the ID card or license presented contains valid claims (information) about the presenter. Information such as name, age, and address are claims that are inherent on the card, while the picture and state seal provide validation that the presenting user matches the user claims, and the state has validated the information. The state is not responsible for how the Service Provider (restaurant, bar, car dealership, etc.) uses the information, just that the information is true and accurate. This is a physical model for the digital concept of the IdP/SP relationship in modern authentication.