auth0 provides authorization to allow a third party service to retrieve your data from the main application. Reminder: authorization is about access to the system, authentication is about proof of ownership of a resource. For example: you, as a developer, want to enable users to import their Google calendar into some application. The question arises how to do this, because only you can access all events in your calendar after authorization. The simplest and weirdest solution is the fields for the login and password, and the application will then make a request for authorization in Google and take the data from the calendar, you are logged in.
There is no guarantee that the application will not store your password in its database and will not use it in the future to its advantage.
By the way, you can still find screenshots on the Internet of how Facebook used to help find friends through gmail. They claim that the screenshot is real. Over time, the developers came to the conclusion that this should not be. To tell the truth, I am sure that most users today would transfer their credits from a third-party service to get the result, no matter how dangerous it might be. So it was necessary to find a solution that allows the user to synchronize their data between services, while doing it as securely as possible — this is the purpose of oauh: to give the application access to a third-party service to collect user data without entering a password for this service.
The main way to keep users safe is to store the password in one place: on the oauth server. That is, if you log into an application through Google, you send your credits to Google, not to the application.
In such cases, the application, instead of asking for your password, redirects to the oauth server, and after successful authorization on this server, the user is redirected back and successfully authorized in the application. The main feature is that the user enters his password directly in the application, which ensures maximum security.
With a brief description of why this is needed, we figured it out, now, before moving on to the authorization methods, a little about the terms that we will use:
- Resource owner: an object that can grant access to a protected resource. This is usually the end user.
- Resource Server: The server that hosts the protected resources. This is the API you want to access.
- Client: An application requesting access to a protected resource on behalf of the owner of the resource.
- Authorization Server: A server that authenticates the owner of the resource and issues access tokens after receiving proper authorization. Auth0 / okta / something self-written.
In the first step, the client requests authorization from the resource owner. This can be directly, as in the screenshot, or (which is preferable) through an authorization service as an intermediary.
In response, the resource owner returns an authorization grand (data granting authorization to the server resource). There are several types of them, we will consider everything later.
Next, the client sends a request to the authorization server to obtain an access_token. This requires successful authentication with grand type
The authorization server detects the client, validates the grand type, and, if all is well, returns the access_token.
The client requests protected resources from the resource server and authenticates with an access_token.
The server validates the token and, if it is valid, processes the request.
The authorization grand, which was mentioned above, is essentially the path that you need to go through to get the access_token and subsequent information. The specification has 4 main types: authorization code, implicit, resource owner password credentials, and client credentials.
This method, perhaps the most common, allows you to get access_token and refresh_token. Oauth themselves call it optimal for client security, because the method is based on redirects.
The peculiarity is that the authorization server is used as an intermediary between the client and the resource server. Instead of asking for authorization directly from the resource owner itself, the client makes a request through the authorization server (okta / auth0 / etc), which returns an access_token. Because the resource owner is authenticated only on the authorization server, the owner’s credentials are never passed to the client (i.e. the password is not passed to the application in which we want to log in).
The scheme is terrible, but, in general, we can say that the scheme consists of two key actions: obtaining authorization (aka access token) and accessing protected resources (directly through which you want to authorize).
Let’s look at Trello as an example of how this whole scheme works. Trello has a familiar login, which allows you to log in by entering a login with a password, and through a third-party application, we are interested in the second.
When choosing authorization through, for example, Google, we are redirected to a new authorization page for a resource that you trust. At this point, we have passed the first 7 points of the terrible scheme. That is: clicking on the continue button through google, tell trello that we want to log in through google. Trello processed this and sent a get request
where the following parameters can be found:
client_id — the trello value obtained when registering the application on accounts.google
redirect_uri — where the user will be redirected after authorization
scope — a list of requested resources
The result of such a request is the application login that we trust
By the way, in some cases it is necessary to additionally press the button that you agree to the processing of your data by a third service, but in this case it was neglected.
After authorization, Google verifies the account on its side, and if everything is successful, returns the code in the parameters to the page selected for the callback. The screenshot shows an example with a localhost.
Next, the client (trello) processes this code and makes a post-request to the authorization server, in this case, Google, to get an access-token
which allows you to pick up the user data requested in the very first request.
The web server redirects the user to the API gateway acting as an authorization server to authenticate and authorize the server to access data on their behalf.
After the user confirms access, the web server receives a callback with an authorization code.
After receiving an authorization code, the web server returns an authorization code to receive an access token response.
After verifying the authorization code, the API gateway sends the token response to the web server.
After providing the token, the web server accesses their data.
This approach provides several important security benefits: client authentication and transfer of the access token directly to the client, which avoids the potential transfer of the token to other resources.
The most interesting part after the user entered their credits. They are verified on the side of the authorization server, and a token is returned. The server resource must approve the user’s access to the application. For example, when authorizing via okta, a notification is sent to the associated okta verify application on the phone. Specifically, this diagram describes the verification option through the code that came to the phone.
In the case of push notification to the phone, you just need to confirm that yes, it is you, after which a similar request will come to the octa server resource, as when entering the code manually. It is verified and, if all goes well, you get access to the protected resource.
Summing up, the chain of events is similar to the previous one: after entering the data, a request is sent to the specified URL for redirection, where the user must enter the code in a special field for confirmation, or click on the confirmation button. After that, a response is sent containing an access_token, which allows you to get data to a protected resource.
Resource Owner Password Credentials
The password credentials of the resource owner (i.e., the username and password) can be used directly as an authorization permission to obtain an access token. Credentials should only be used if there is a high degree of trust between the resource owner and the client (for example, the client is part of the operating system of a device or a highly privileged application) and when other types of authorization permission are not available (for example, an authorization code).
Although this type of permission requires direct client access to the credentials of the resource owner, the credentials of the resource owner are used for one request and exchanged for an access token. This type of grant can eliminate the need for a client to store the resource owner’s credentials for future use by exchanging the credentials with a long-lived access token or refresh token.
Client credentials (or other forms of client authentication) can be used as an authorization permission when the scope of the authorization is limited to secure resources under the control of the client or secure resources previously negotiated with the authorization server. Client credentials are typically used as an authorization permission when the client acts on its own behalf (the client also owns the resource) or requests access to protected resources based on an authorization previously negotiated with the authorization server.