Quote of the Day

more Quotes

Categories

Buy me a coffee

  • Home>
  • security>

Building or leveraging an OIDC provider to protect web applications.

Published August 24, 2020 in OAuth2 , OpenID Connect , security - 0 Comments

In this post, I write about OpenID and OAuth2 providers, and what can you use to build or leverage them to protect your web applications.

Before discussing about OpenID Connect and OAuth2, let’s talk about one of the traditional mechanisms to authenticate the users, form based authentication and its drawbacks.

Form based authentication

In a typical web application, the backend includes a database which stores users’ accounts, and the frontend includes screens for login, registration, profile editing, password reset etc.. The login screen consists of a form for the user to enter credentials within the app. On login, the application validates the credentials against the database and gains access to the user. Everything happens within the app. This type of authentication which a user enters username and password directly to the app is form based authentication.

Form based authentication has several drawbacks.

Form based authentication makes it harder to adhere to the DRY principle. For instance, suppose a company has multiple, related web applications, each with its own database to store the users’ credentials, a login screen, a registration screen and security logic to validate the user. The logo and most of the screens’ inputs are similar across all apps. The registration screen may include fields such as username, password, age, occupation etc… The login screen may include inputs for username and password. On login, the app checks against the database, retrieve the user’s info and allow access if everything checks out. It would be nice if we can reuse the screens and the authentication logic. However, because the security flows do not adhere to specifications, it’s hard to share them between applications.

Another drawback of form based authentication is lack of granular control over which aspects of an app the user can access and the length of access. An attacker is able to impersonate the user if he or she knows the credentials for as long as the user is unaware to change the password. When the user has finally realized the account is compromised, serious damages may have already occurred. Using multi factor authentication can help to mitigate this risk.

Requiring a user to create an account for each app lessens the user experience. As a user, I prefer using my social credential to login to a new site. If that’s possible, I want to use only a single credentials when accessing related sites developed by a same company. For example, with a google account, I am able to login to multiple Google products such as YouTube, Google Drive, Google Photos etc …

In the example of a company with multiple related apps, a better architecture would be to abstract out the identity management into a reusable module for sharing between the apps. This module would be responsible for authenticating the user and returning the results to an application which can gain or deny access based on the info. By extracting the identity management out of the apps, we can avoid duplicating codes and resources as each app no longer need to maintain separate resources and logic for managing the user’s identity. If we want to support social login, instead of making changes to all the app, we can just update the identity module. However, building the identity module that works well for multiple apps is complex. On one end, the apps must be able to verify and trust the results from the identity module. Otherwise, someone may provide forged results to gain access to the apps. On the other end, the identity module needs to identity the apps for which it allows the user access. Otherwise, an attacker may forge an app, send the user to identity module and interpret the results to solicit info about the user. Only authorized apps should have access and able to decipher the results from the identity module.

OAuth2 and OpenID Connect protocols.

Because building such an identity module is complex, it’s better to have open protocols such that the identity module can interoperate with applications not only from within an organization but also with any application that understand the protocols. Fortunately, we don’t have to reinvent the wheels. The smart people in our field have already came up with standard protocols called OpenId Connect and OAuth2, and there exists several popular frameworks as well as SASS products that implement these protocols. In a nutshell, OAuth2 protocol defines the different types of authentication flows, establishing trust between applications, the authentication result in a form of json web token, the roles each component plays in an authentication flow, which aspects of an application (scope) a user can access and much more. In OAuth2, the server which authenticates the user or a client application and issues a json web token is called an authorization server, and the token is called an access token. The server which hosts the resources a user or a client app needs to access is called a resource server. Although a user or an app needs to authenticate against the authorization server, OAuth2 is about authorization, not authentication. This is an important fact that I misunderstood a while back. In fact, the access token is meant for the resource server to determine the scope of access a client should have and the duration.

The access token represents the grant’s scope, duration, and other attributes granted by the authorization grant.

The OAuth 2.0 Authorization Framework: Bearer Token Usage

However, there exists deviations from the standards to make OAuth2 work as both an authorization and authentication framework, by leveraging the fact that a user or app has to authenticate against the authorization server to obtain the access token. Deviating from the standards is problematic because it defeats the purpose of having OAuth2, which is interoperability among different systems.

OpenIDConnect- OIDC builds on top of OAuth2 and provides standards to obtain the identity of the user. OpenIDConnect introduces a json web token type called id token, which includes claims about the identity of the user which authenticates against the authorization server.

What is an OIDC identity provider?

An OpenID Connect (OIDC) provider is an identity provider that conforms to the OIDC protocols to allow interoperability between different types of systems that understand or implement the same protocols.

Hopefully, you now have some ideas about OAuth2 and OpenID Connect protocols. Let’s look at some options to build or use a OpenIDConnect identity provider to protect your web applications.

Build your own identity provider

I don’t think one should set out to build an OIDC provider without utilizing a framework because of all the complexity and rules specified in the protocols. To build an OIDC provider, you’ll need to implement token signing and encryption, registering applications, authentication flows, defining scopes, different claim types, user endpoint, discovery endpoint, federating to other providers etc… Not only do you need to implement the protocols, you also need to make sure your implementation is secure and can prevent various types of attacks such as token substitution, open redirector, timing attack, token reuse etc…

It’s good to read and understand the protocols. However, when it comes to protecting your APIs, you should leverage an OIDC provider framework that has been tested and trusted by big corporations. One such framework for .NET is IdentityServer4, which is open source. If you are a Java developer, you may want to look at utilizing Spring Security to build your OIDC identity provider.

Use a framework

IdentityServer4 is an open source security framework which implements OpenID Connect and OAuth2 specs.

IdentityServer4 provides models and implement registering client applications to different storage mechanisms. Out of the box, the framework supports storing data in memory or a database using entity framework. You can also plug in your own storage by implementing the interfaces.

Building an OIDC provider involves much more than just registering client applications. An OIDC provider needs to support different grant types for different authentication scenarios: implicit, authorization code, hybrid, client credentials, and proof key for code exchange (PKCE). IdentityServer 4 has implementations for these grant types. All you need to do is to specify the ones you want to support. For more info, checkout the doc.

Other complexities of an OIDC provider include token generation, token signing and encryption, key management and rotation, session management, claims type, federating to social and external providers and much more. Fortunately, IdentityServer4 handles most of the low level implementations for you. As of this writing, IdentityServer4 provides primitives to help with key rotation process. However, you still need to do more work to achieve automatic key rotation, or use a commercial product. To learn more, checkout the blog.

A common architecture is the so-called federation gateway. In this approach IdentityServer acts as a gateway to one or more external identity providers.

../_images/federation_gateway.png

FEDERATION GATEWAY

Using a framework such as IdentityServer4 has many benefits. You save time and effort by leveraging the existing work of brilliant people. Not to mention using a framework is likely to be much more secure than implementing from scratch because it has been tested collectively by the community. A good framework like IdentityServer4 provides a solid implementation of the OIDC specs, as well as great customizations and extensibility by allowing you to implement its interfaces.

IdentityServer4 is a great choice for many developers and software companies. However, you still need to write codes to configure and customize your identity provider. Depending on the grant types you want to support, you may also need to build your UI pages for login, registration, password reset and other account management because the framework does not provide default implementation for them out of the box. For example, for implicit grant type, you need to build the login and registration page as the grant requires a user to authenticate against the authorization server.

As an analogy, you can think of IdentityServer4 as a car’s manufacture which has all the components you need to build a car. You can choose the engine, body type, brake, steering wheel etc … However, you still need to assemble the car from the components, which can still be a time consuming and tedious task. Sometimes, you may just want an already built car from a dealership. With the built car, although you likely can’t change the body type or engine, you can add accessories such as GPS, alarm or extra layer of paint protection etc …Similarly, if you want an already built identity provider, you can use a software-as-a-service product such as Microsoft Azure ADB2C.

In terms of pricing, IdentityServer4 is an open source framework, which means you don’t have to pay to use it. Ofcourse, you still have costs for server to host your identity provider, persistent storage and other resources unless you are testing or use in-memory storages.

Use a SAAS

Another option of building an OIDC provider is to use software as a service such as Azure ADB2C. Azure ADB2C is a complete OIDC provider with a decent portal for registering and managing client applications, claim types, grant types, built in user flows with default UIs for sign up, sign in, password reset, and profile edit. It has its own data store which is based on Azure AD for storing configurations, users’ credentials, and roles.

Another great feature of Azure ADB2C is federating to social and other OIDC provider. For example, Azure ADB2C provides built in support for popular social providers including Facebook, LinkedIn, Github, Twitter, and Amazon … You can also add any OIDC provider via the portal. For example, you can federate to another Azure AD tenant from Azure ADB2C.

If you use Azure ADB2C, most of what you need to get up and running is to register the applications, configure permissions and scopes, and add the user flows to use. All of these can be done via the portal. The best part is you can apply custom UIs to the flow to apply brandings and integrate seamlessly with the rest of your applications.

Azure ADB2C user flows

Furthermore, you can extend AAD B2C using custom policies. Under the hood, the built in user flows are defined by XML schemas which you can extend. For instance, you can code a custom flow in XML to call your web API as part of authentication. However, per the document, you should try to use built in flows as they are much easier to maintain.

Azure ADB2C also has built in support for email verification and multi factor authentication.

In terms of pricing, the cost depends on the number of active users per month. For instance, it can be free to use Azure ADB2C if your system does not have more than 50,000 active users per month. In this case, Azure ADB2C can be the cheapest options, as you do not have to incur costs of hosting a server and persistence storage. However, Azure ADB2C does have separate charges for multi factor authentication and SMS phone events.

Azure ADB2C is a great choice for the scenarios below:

  • You want to get setup and running quickly with an OIDC provider.
  • You don’t need to go with a specific data persistence store.
  • You don’t need much customizations to the built in flows besides defining claim types and custom layouts.
  • Your organization is already using Office 365 or Azure AD.
  • You want to delegate storing and protecting users’ credentials to a third party provider.

Wrapping up.

Form based authentication has several drawbacks which include lacking mechanisms to reuse codes and systems, not easy to support single-sign-on, less convenience and secure. If you are building a new application, consider using an OIDC provider to protect your web applications so you don’t have to concern with identity management and have much greater flexibility, security and interoperability with other systems that understand or implement the same protocols. To quickly get started, I recommend you take a look at Azure ADB2C or IdentityServer4 to build your OIDC provider.

References

Identity Provider

OpenID Connect Core 1.0

OpenID Connect FAQ and Q&As

OAuth

The OAuth 2.0 Authorization Framework

Introduction to Json Web Tokens

Claims-based identity

IdentityServer4

IdentityServer4 supported specs

What is Azure Active Directory B2C?

Azure Active Directory B2C pricing

Spring Security Reference

No comments yet