Design Pattern - Adaptive Policy-aware Step-up Multi-factor Authentication

Design Pattern - Adaptive Policy-aware Step-up Multi-factor Authentication

Often it is the case, when you have your own Identity system(s) to perform Primary Authentication to your applications, but want to enhance authentication with a centralized Multi-factor Authentication Service, that takes Contextual and Behavior based factors into account.

In this post, I will develop such a pattern leveraging Okta. The pattern described here is universally applicable to web based, mobile or desktop applications.

# Okta Overview

Okta connects any person with any application on any device.

It's an enterprise-grade Identity Management service, built for the cloud, but compatible with many on-premises applications. Okta runs in the cloud, on a secure, reliable, extensively audited platform, which integrates deeply with on-premises applications, directories, and identity management systems. Okta features include Single Sign-On (SSO), Provisioning, Multi-factor Authentication (MFA), Mobile Identity Management, and flexible policies for organization security and control.

For more details on Okta offerings, visit here.

# Why Special Pattern

One obvious way to introduce MFA to your application, is to integrate Okta as your central authentication provider, and let Okta handle the authentication and MFA scenarios automatically.

In reality though, integrating Okta for authentication might not be the feasible solution due to a number of reasons -

  1. Your applications might be using proprietary or non-standard authentication systems, and there will be significant disruptions attempting to integrate Okta as the authentication service provider. That could be prohibitive in terms of budget and resource.

  2. Many of your applications are Desktop-based with no web browser interactions.

  3. You do not want to store user credentials in a cloud based service. At the same time your user repository is not Active Directory or LDAP, so Okta may not be able to delegate authentication to your Identity system. For example - your application perhaps leverages a database table to store user credentials.

There are other techniques possible to achieve delegated authentication to different kind of Identity repositories. Here, I am assuming that you will continue using your existing authentication process without integrating Okta as the front-end authenticator.

# Considerations

Okta provides stand-alone REST based MFA API's (Also called Factor API's), that any application can use directly to leverage the MFA service. For providing basic MFA service, those API's are sufficient and you do not need anything further.

However, those API's are stand-alone. More specifically, they do not honor any Contextual and Behavior based MFA policies. Okta provides a rich set of capabilities to centrally configure and manage MFA policies across applications and users. Using stand-alone API's, you lose the ability to take advantage of those policies.

Moreover, the stand-alone Factor API's need to use API Token. API Token needs to be protected and secured. Hence this approach is not suitable for client side applications and needs a secure backend service for API processing. Also, additional management overhead is there for securing and managing API Token.

It is clear, in order to leverage Okta's rich policies, the application needs to simulate some form of authentication flow with Okta.

# A Workaround

This is a hacky way to accomplish the goal that will open you up to severe security vulnerabilities. DO NOT DO THIS.

A quick-and-dirty way to call policy aware MFA API, is to secretly simulate standard authentication flow.

Okta can store user passwords based on some pre-computed logic. For example, you can implement a hashing algorithm to generate passwords based on the user's login id or combination of some other attributes.

Once users have predictable passwords, your application can recompute the password before calling Okta's password authentication API; then Okta will respond based on the defined Authentication Policies. If MFA is needed, then the response will prompt for MFA challenge, and allow the user to respond to the MFA challenge.

However there are multiple drawbacks to this approach -

  • User's password is inferable. Without additional measures, your system is at risk and exposed to abuse.

  • There is an additional authentication flow under the hood, in addition to your own Identity system authentication. So, architecturally the solution is more like a workaround.

# Introducing the pattern: Factor Sequencing

How about going Password-less 🎉? By leveraging Okta's Factor Sequencing, you can completely bypass the password authentication and still carry out the MFA operations.

On a high level the steps will look like the following -

  • Configure Factor sequencing in authentication policy
  • Use factors such as Okta Verify, SMS, FIDO2 etc
  • Start the authentication flow using authentication API without providing password
  • Pass end client information on your API call

Okta Authentication API will evaluate the authentication policies. If authentication is allowed by the policy, the response will challenge user with MFA. Your application can then call the API to verify user's response to the challenge and fulfill the MFA flow.

# Benefits

The benefit of this approach is that the Multi-factor Authentication step can be performed entirely from the browser or client side code (mobile/desktop), and no Server Side code is required and no Okta API Token is needed.

# Architecture

Here is the sequence diagram of the password-less design pattern for the MFA flow.

Sequence Diagram

# Implementation

Checkout this single page application, leveraging the design pattern to achieve step-up MFA, where the primary authentication is not using Okta.

https://github.com/indranilokg/Okta-MFA-Everywhere

# Demonstration

# How it works under the hood

After user logs in to the application using internal identity system (not Okta), and initiates a transaction, the application starts the authentication flow with Okta passing only the user id and user's application context information.

POST /api/v1/authn HTTP/1.1
Host: https://*******.okta.com
Accept: application/json
Content-Type: application/json
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
Content-Type: text/plain
{ "username": "dcrane@mailinator.com" }
Notice that no credentials are passed in the API Call to Okta.

Okta evaluates user's context from the HTTP headers and applies the authentication policies. If the user is not authorized based on her application context, Okta sends an Unauthorized response.

Otherwise Okta returns a response with a stateToken and a list of enrolled MFA factors to choose from. The application then prompts the user to choose an MFA factor and then calls the MFA API with the chosen factor.

POST /api/v1/authn/factors/smsqufwjrnT7fvcVR0h7/verify HTTP/1.1
Host: https://*******.okta.com
....
....
{ "stateToken": "00CIWUamZgqt9Rfs1RIitioKRL7h7IWcKY0wqCVneC" }

User receives an MFA challenge as a response. For example, if the chosen factor is SMS, then user receives an OTP in SMS to her enrolled phone. User responds to the MFA challenge. Application calls the MFA API to verify the MFA response.

POST /api/v1/authn/factors/smsqufwjrnT7fvcVR0h7/verify HTTP/1.1
Host: https://*******.okta.com
....
....
{ "stateToken": "00CIWUamZgqt9Rfs1RIitioKRL7h7IWcKY0wqCVneC", "passCode": "477492" }

Finally, Okta evaluates the MFA response and sends back the verification status. Application allows the transaction to proceed, if the verification response indicates successful MFA.

# Caveats

In order to leverage the password-less pattern, users still need to have passwords generated for them. However, the passwords could be entirely random and never need to be known to anyone including the users.

Okta is introducing Identity Engine, that will have more sophisticated password-less authentication flows.

# Summary

In this post, we have seen the design pattern to leverage Okta's password-less capabilities to provide policy aware step-up Multi-factor Authentication service to an application. The pattern leverages Okta's organization-wide contextual authentication policies.

Read More