One-Time-Password authentication flow with client, server, database and Auth0 - oauth

I am trying to implement the OTP authentication flow with SMS using Auth0 (Passwordless Connections with SMS using Twillio).
We have a mobile app, an API, a database and we use Auth0.
Steps:
The user enters a phone number.
Does the client send directly the phone number to Auth0?
Or Does the client send the phone number to the API which calls Auth0 (Twillio)?
The user receives a code through SMS
Does the client send the code to Auth0?
Or Does the client send the code to the API which then sends it to Auth0?
The user enters the code and receives an access_token, an id_token and a refresh_token
Does Auth0 talk directly to the API and the client separately?
Should the client receives these tokens and send it to the back end?
Or Should the API receives these directly and send back to the client only the id_token?
the user accesses the resource in the database.
Does the id_tokem, access_token and refresh_token need to be saved in the database?
These are a few questions I have but I am more confused about the general authentication flow with OTP.

The Auth0 helps you to handle authentication process and your API needs to determine what users can and cannot access with each request. This process is known as authorization. In other words authentication starts on the client-side, while authorization starts on the server-side.
AUTHENTICATION (client)
In your example, client sends directly the phone number to Auth0, Auth0 (Twillio behind the scene) sends back the code.
Client sends back the credentials(phone number and code) to Auth0 that validates them. Once the code is successful, Auth0 encapsulates access information in something called an access token (JWT- JSON Web Token) and identity information in something called an ID token. More about tokens here https://auth0.com/docs/tokens
The mobile application stores the access token and refresh token locally.
AUTHORIZATION (backend)
When the user needs to make a request to a protected API endpoint, the client application must send the access token with the request for the API to then carry out the authorization process. The access_token must be in the authorization header of every request it makes to protected endpoints.
The server validates the access token. If access_token is not valid, use the refresh token to obtain additional access tokens. If valid, the server determines if the token bearer can access the requested endpoint using information within the token.
You server (point 3 in your question) needs few things to start authorization process. You will have to validate the access token using JWT Strategy. If you are using nodejs, there is a good module called Passport which can help you with that.
To configure JWT Strategy you'll need two values from Auth0: an Auth0 Issuer URL and an AuthO Audience. You will get these values by creating api in Auth0 dashboard.
That means Passport validation is all handled by Auth0 in your created tenant (api) in Auth0 dashboard. Auth0 determined the identity of the logged-in user and then passes data about the user within payload object which you can access throughout the request-response cycle through controllers and middleware.
Your protected endpoints e.g /account automatically invokes your JwtStrategy configuration logic and blocks request if the access_token is not valid.
This article helped me a lot to understand OAuth flow which I quoted here a lot :) https://auth0.com/blog/developing-a-secure-api-with-nestjs-getting-started/

Related

Clarification needed on why Client application should need both idtoken and access token

Client application fetches the idtoken for authentication. But for the resource server, it needs to again make a call to Auth server and fetch the access token. Hence, does it make sense to make two calls for every oauth2.0 flow. The access token is what will be sent to the resource server. Am I missing something here.
With OpenID Connect, the ID-token is returned to the client at the same time as the access-token. So there is no specific need to make two requests to get the two tokens.
If you ask for an refresh token as well, then that one will also be returned at the same time.
The API (Resource Server) only receives access tokens from the client and it can without asking the identity provider validate the token. The API does not receive any ID-token.

Authenticating using Auth2 when there are several resources

I need to implement a single sign on of a user, which can get services from several different services.
When there was only a single service, the user could log in from the client side, send the request to a backend, gets a URL back to a JWT token issuer server, from which he can get a token which he sends back to the BE and he is now authenticated.
What is now changing, is that he needs to get more services. Each service has its own frontend and backend, but everyone are using the same issuer. Meaning there are both services with FE and BE, and also there is another general BE for the authentication.
What is the correct flow to authenticate in the scenario? Can the general BE issue a token for the client for each of the required services? Or should the BE respond the client with the services's BE url and let the client itself send an authentication token response from each service? Or something else?
I assume you mean OpenID Connect, since OAuth2.0 is not used for authentication and does not require the use of JWTs. Also, in your scenario there are not multiple resources, but multiple clients / relying parties.
Using the OpendID Connect Implicit flow, the issuer will eventually send an id token (JWT) to the user's browser. This JWT can be used to authenticate to a service. Each JWT will contain an aud (audience) claim to identify the service it should be used for.
Using the Authorization Code flow, the issuer will eventually send an authorization code to the user's browser. The user will send the code to a service, and the service will send the code plus its client id to the issuer in exchange for an id token (JWT) and an access token.
In both cases, the service identifies the end user using the iss (issuer) claim, and verifies the JWT by checking the signature, expiry and audience.

With OAuth2, should I send the auth code or tokens to the service from a mobile client?

So my understanding of OAuth2 from a mobile client is:
Mobile client redirects page to get user auth using client id
Resource holder responds back with an auth_code
auth_code is exchanged for an access_token and refresh_token
In the above, if you have a web service that is acting to support your mobile app, you permanently store the access_token and refresh_token, which will allow you to continue to access the user's data, provided they haven't revoked your permissions.
So the question I had was: should the auth_code be sent to the service, and exchanged there for the tokens? Or should the client exchange the auth_code, and send the resulting tokens to the service? Does it not matter, or is it perhaps different for different implementations? I'm assuming the client secret is only stored on the service, and my understanding is that is needed to exchange a refresh_token for a new access_token, but I wasn't sure about the auth_code.
The client secret is needed also when requesting the tokens using the authorization code.
The client can request the tokens directly or delegate that to the service - there is not a hard and fast rule saying you should do one or the other.
I'd say if the service is going to use the tokens probably delegating to the service makes most sense - so the tokens stay there. If the client is going to use the tokens both approaches are valid.

How to use OAuth2 to implement a third-party login/register?

Here is my plan (authorization code flow) of implementing such login/register logic. (The third-party only provided the OAuth2 API)
First the SPA frontend will send a GET request to the third-party
GET https://www.example.com/oauth2
client_id=dummyclient
redirect_uri=https://mysite/callback
response_type=code
scope=openid
Then if the user agree to give his/her openid to mysite then the fronend will get a 301 HTTP response.
---> 301 https://mysite/callback?code=dummycode
Then the browser will redirect the page to mysite/callback and it will reload SPA and expose the code in URL which can be captured by the SPA then it will send the code to the real backend callback.
GET https://mysite/api/real-callback?code=dummycode
When the backend get the code, it will send the code to the third-party to exchange an access_token. When the backend get the access_token, it will fire an API request to get the user's openid then decide whether to let the user login or register as a new user. At last it will give back a HTTP response to our SPA frontend which contains the access_token in my OAuth2 system or a 401 unauthorized response.
So my question is how to prove that the real callback is invoked by my own clients (Because if some attacker get my frontend embedded client_id then he can fake the OAuth2 request and phishing the user to agree. After that the attacker will get a valid code then he send back the code to my real callback. Finally, he will get the user's access_token in my system.) How can I use OAuth2 to do authentication without the end user's providing additional information like password.
I would suggest you to change the OAuth2 flow to Implicit and ask for both access_token and id_token (OpenID Connect). Your SPA will get the tokens, send the ID token to your backend, which can use it to decide whether it's possible to create such user. The SPA can use the access token to call protected resources.
This way,
only the SPA will be an OAuth2 client - tokens will not be used by two applications (SPA and backend),
you will have just one redirect URI,
you will not need to transfer tokens from the backend to the SPA.
Update: Without OpenID Connect
If you cannot use the id_token, you could send the access_token to your backend and the backend can get the user's username by sending to token to the Introspection endpoint https://www.rfc-editor.org/rfc/rfc7662 (from the response username attribute). The username attribute is optional. Your OAuth2 server may return even more info (such as name and email).
This Introspection endpoint requires authentication, so to use it, your backend will have to be a registered OAuth2 client with its own client_id and a secret.

oAuth2.0 access token confusion

I am following this tutorial about OAuth2.0 https://developers.google.com/youtube/v3/guides/authentication
It looks quite clear how OAuth2.0 works. But I have a bit confusion at the access token part.
After obtaining an access token for a user, your application can use
that token to submit authorized API requests on that user's behalf.
The API supports two ways to specify an access token: Specify the
access token as the value of the access_token query parameter:
www.googleapis.com/youtube/v3/videos?access_token=ACCESS_TOKEN
if someone acquired this access token during the url transferring they can access this protected resource right?
How the server know if the request is coming from the client initially requested the access token?
UPDATE:
after reading this post Are HTTPS headers encrypted? my confusion is cleared. I thought query string is not encrypted during transmission in the network.
Generally I think the consensus is that OAuth 2.0 is a server side technology and all access tokens and communication should be transmitted using SSL as the bearer tokens need to be kept as secure as possible.
Also, you need to know that there are 2 types of flows in OAuth 2.0
i) Implicit grant flow - This is the flow where the user logs in to the service provider and his browser gets the access token. Say you have X.com and Log in via Facebook. Once the user keys in his FB credentials, the access token is sent to his browser.
ii) Authorization Code flow - In this flow (consider the above situation again), facebook will pass an authorization code to the user's browser. If anyone, somehow, intercepts the authorization code there is nothing he can do. An authorization code can be exchanged for an access when passed with valid client credentials. So, when the user logs in, his browser gets an authorization code which is passed to your server at X.com. from there you would hit the code-token exchange endpoint provided by FB and get the access token returned to your server!
Authorization code flow adds another layer of security, where the access token is visible only to the client + server and not to the user agent. And as you figured out yourself, the token is passed via HTTPS.

Resources