Basic-Auth is deprecated. How about OAuth 2.0 and OpenID Connect?
In this article, you will learn the basics of the OAuth 2.0 authorization framework and a simple identity layer which located on top of the framework – OpenID Connect.
Introduction
Before OAuth, the common pattern for granting access to an external application’s account was to simply give it your password and let it act as a you. Communication always consisted of entering the user’s password in the application and then using it to get access to a particular service with data. Thus, the application was given access to the entire user account, even though in truth it only needed access to part of it – the scope was much broader than realistically needed.
Once the application has obtained the user’s password, it is granted unlimited access to the user’s account, including access to capabilities such as changing the password. Additionally, these passwords were stored in plain text, which makes them vulnerable to a potential attack. Another problem was that after providing an app with your password, the only way you would be able to revoke that access was by changing your password, something that users are usually reluctant to do.
Companies realized that such solutions are not safe and unfriendly, so they started implementing their own solutions. As a result, in 2007, the OAuth framework version 1.0 was created. But not all things were clarified, many of the aspects were difficult or confusing and a revised version 2.0 of OAuth was launched in 2012.
Authentication vs Authorization
To understand exactly what the framework is all about, two terms must first be explained. Authentication and authorization, although often used interchangeably, represent fundamentally different functions. To put it simply, authentication is the process of verifying who the user is, while authorization is the process of verifying what the user has access to. Let’s take a quick look at the differences between authentication and authorization.
OAuth deals with authorization and its main purpose is to delegate authorization. Basically, it answers the question: How can I let an app, access my data, without giving it my password?
OAuth 2.0
So, how does it all work?
When an app wants to access your data, e.g., contacts, it simply redirects you to an authorization server (which you’re probably already logged in), where you are then greeted by the consent screen, telling you what specific data the app will be able to access in your account, if you allow it, and all this without entering your password.
Such a process has many benefits:
- The password remains only in the service that knows it, it is not required externally, e.g., in another application
- The range of permissions is defined, there is no more full access to user account
- The probability of password leakage is much lower, because thanks to this solution we do not disclose our password to the application we are using
- Also, the fewer screens for entering a password, the lower the risk of password leakage
- All processes such as password reset, password change, two-factor authentication are then in the logic of the authorization server, so the user does not need to implement this in each application
Roles in OAuth
Client Types
The application must be registered and configured on the authorization server before the whole process begins, one of the most important data is the client type. There are two client types in OAuth 2.0:
- Public – unable to use registered client secrets, such as applications running in a browser or on a mobile device.
- Confidential – applications that can securely authenticate with the authorization server, for example being able to keep their registered client secret safe.
Grant Types
The OAuth specification allows for several ways to obtain and validate tokens, which are named – grant types or commonly flows. Not all grant types are intended for all types of clients.
The basic steps to configure an app and obtain an access token are following:
- Register your app in authorization server with following data:
- Client ID
- Client Secret
- Redirect URI - Select scope of your access
- Make a request using the grant type that suits your app
The most popular and commonly used grant types are:
- Authorization code grant with PKCE – for public clients like native apps – JavaScript, mobile apps.
- Client credentials – for confidential clients, and therefore for machine-machine communication and always when you can store your secret safely.
Authorization code grant with PKCE
This grant type is the most common OAuth flow. To obtain a token using this flow, the client sends an authorization request to the OAuth server. The server makes sure that the user is authenticated and asks the user to approve this request. Once the user approves the request, an authorization code is issued, which the client passes back to the authorization server and a temporary access token is issued to the client. The client can now access the resource from the resource server by providing this access token.
Together with the access token, a refresh token is also issued to the client, which can be used to generate a new access token without user interaction.
PKCE is an extension to the Authorization Code Grant that improves security and is a recommended solution for all types of applications. The client app creates a unique string value – code_verifier, which hashes a code_challenge. When the client initiates the flow, the code_challenge is sent in the request. Then in the normal flow the authorization code is issued, and the client passes it back to the authorization server but now together with code_verifier. If the codes match, then the access token is issued to the client.
Client Credentials
In this grant type the client can request an access token using only its client credentials. The flow begins with an authentication request which contains the client ID and client secret. Then the Authorization Server validates the client credentials and responds with an access token, which the client can use to access the resource from the resource server.
Client Credentials grant type is used by applications in isolated environments like backend where the user context is not needed. It is mainly used in machine-to-machine communication and must only be used by confidential clients due to the need to store client secret.
OpenID Connect
OpenID Connect is a simple identity layer located on top of the OAuth. It extends the OAuth authorization framework for use as an authentication protocol as well.
The process flow is the same as OAuth 2.0. The only difference in the authorization request is a specific scope – openid. In the final response, in addition to access and refresh token, the ID token is also provided to the client. The ID Token contains information about the user – ID, name, email, etc. One important thing is that the ID Token should never be used to obtain access to API.
An ID token is a specifically formatted string in form of a JSON Web Token – in short JWT. The identity information about the user is encoded right into the token and the token can be definitively verified to prove that it has not been tampered with. It is worth mentioning that the information in ID token can become obsolete, for example if the client wants to read data from a token which they received some time ago. For this purpose, OpenID provides an endpoint in its standard called UserInfo endpoint. This endpoint is used to obtain fresh user information and must be called with an access token.
OpenID Connect supports scenarios in which a single login can be used across multiple applications, also known as single sign-on (SSO). For example, an application can support SSO with social networks, allowing users to use a login they already have and are comfortable using.
Conclusion
OAuth 2.0 is a widely used framework based on HTTP protocol, which makes it compatible with almost any platform. OAuth is also constantly being developed and have very good documentation. Together with OpenID Connect on top, it is a highly recommended solution for implementing both authentication and authorization processes. For more detailed information, I refer you to the official site along with the RFC documents: https://oauth.net/2/