OAuth Procedure: Request Twice to Server - security

I am a beginner to OAuth so my question might sound naive. I found this picture online describing how OAuth works.
Let's say the client already did the authorization before, which means we already know which authorization the clients get.
So, for the second time when the client request the authorization, I am not sure why can't we request the authorization from the client and return the protected resources from the server back to the client? So basically we skip steps 2, 3, 4 and 5, and we only keep steps 1 and 6.

What are you looking at there is the "Authorization Code Grant". This means you have an authentication service that is capable of serving back a login form to the user, authenticates them and then issues a grant. This grant is then turned into an access token via another call.
If you want to do application level authentication then use the Client Credential Grant
This means that you have a ClientID and ClientSecret which identify an application, not a user. You issue a request with those and you get back a token you can use to access a protected resource.
An example is here: https://eidand.com/2015/03/28/authorization-system-with-owin-web-api-json-web-tokens/
If you want to use user credentials for authentication then you can use the Resource Owner Password Credential Grant for example.
So, it all depends on what you are looking for.

Related

OAuth clarification

I've followed a training in Go as an introduction to microservices architecture a while ago. Getting back to this project I realise that I need more context as we've been quickly digging into the details of the implementations at the time...
I've drawn a simplified sequence diagram of 2 simple use cases:
The user logs in
The user is already logged in and make a purchase
(you can comment / modify the diagram at your convenience)
https://drive.google.com/file/d/1gWgkhJipUvWrVidkl7YFt_xlDmZYn_CX/view?usp=sharing
Here are the questions I have:
Here we're dealing with user authentication but what about client authentication? In the case of a web front end client, can I imagine storing an api_key and an api_secret in the env variables for the server that will be hosting this client? Because there use cases where the user is not logged but some services still needs to be available, but at the same time I only want my known clients (the web front and the mobile app) to be able to access those services (putting aside API Gateway solutions, and maybe other API Shields which would probably add another security layer against DOS etc.)
If the client logs in using Google/Facebook, the front app will receive an id_token that needs to be passed to the backend which would then verify the token ( https://developers.google.com/identity/sign-in/web/backend-auth ). In this particular case my OAuth API would not be used. Could please you confirm that it's the way it should be handled?
Many thanks.
EDIT 02/05/2022
Intro / Context
First thing first, Authorization is not Authentication.
Authentication is the process of verifying who a user is,
while authorization is the process of verifying what they have access to.
And like #Max said, OAuth is designed to manage Authorization and Open ID Connect (OIDC) is an extension of OAuth to manage Authentication on top of it.
The diagram I've exposed in my question is known in the OAuth world as the password grant, and, from the official documentation :
Because the client application has to collect the user's password and
send it to the authorization server, it is not recommended that this
grant be used at all anymore.
Authorization of my App (to get access to my APIs)
From the API perspective, we just want to ensure that the incoming requests are coming from the server that is hosting the App. So, in my case, it's simple machine-2-machine communication from backend server to backend server and there's no action required from the user. So, I must implement the Client Credentials Flow
...which would lead me to this flow:
https://drive.google.com/file/d/1qE9JpWRSRPa8z5iNxm7ocGkeT0E149Sv/view?usp=sharing (Feel free to comment / rectify )
Authentication of a user
Because OAuth knows nothing about authentication, I need an OIDC flow. The easiest one is based on the Authorization Code Flow with PKCE from OAuth below (only about authorization) ...
... but the difference is that we're passing an additional scope named openid in the authentication request (step 3), when the app performs the 2nd request to the token endpoint (step 7), the auth server returns an ID Token (which is a JWT containing user info in the payload -> authentication) in addition to the access_token (which do not contain user info but just "random string"). There's other OIDC flows with their pros & cons depending on the situation but it's another topic on its own (https://openid.net/specs/openid-connect-core-1_0.html)
User already identified by Google/Facebook
In case the client logs in using Google, the front app will receive an id_token. This token could be sent to the app server which would then make a request to the API Gateway, which then call the Auth api which would be in charge of verifying the token by calling the 3rd party auth server ( https://developers.google.com/identity/sign-in/web/backend-auth ).
In case of Facebook, we get back an access token, so I don't know how to deal with it ...
https://developers.facebook.com/docs/facebook-login/web
https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow
Using Firebase, there's an onAuthStateChanged callback, so from the App perspective it will prevent request without the user being logged in, but from the API perspective, it doesn't guaranty that a request is coming from a logged in user...
https://firebase.google.com/docs/auth/web/manage-users#get_the_currently_signed-in_user
Warning: the answer below is not complete, it only serves to give a rough idea
Intro
OAuth2 is a protocol for authorization.
Grant Types
Over the OAuth2 protocol, you can use one of the "grant types" or "flow", one of these flows is illustrated in the picture you post and named password grant.
Each of these flows is realized for different scenarios, you rightly point the attention to how securely store the password on a web app.
For example for a front-end authentication (javascript / wasm) you can use a PKCE Flow where the secret_id is not used.
Endpoints
On OAuth2 there are two primary enpoints
Authorize endpoint - where you obtain the authorization code
Token endpoint - where you exchange the authorization code for the token(s)
Tokens
There are two types of tokens on OAuth2
Access Token
Refresh Token
The definition of token on OAuth2 is "an opaque string", you don't need to read it.
The access token is used against the API, this token has an expiration date, when it is expired the system use the refresh token to get another access_token whitout user interaction, when the refresh_token expire the user must re-authenticate again.
You can read the content of the access_token (which is a JWT token) from the JWT.io
Scopes
The Access token has, on its body, the scopes (i.e. Read email, read name, etc).
Scope is a mechanism in OAuth 2.0 to limit an application's access to a user's account.
Identity
On top of the OAuth2 are build other protocols OIDC aka IdToken aka Open Id Connect is one of them, in other terms OIDC protocol use the OAuth2 for establish an Authentication.
With the OIDC there is another token the id_token, this token came with the user's info and is NOT used has Authorizization in front the API.
There are also OIDC flows you can use to get the id_token and/or the access_token.
Conclusion
I suggest you read about OAuth2 from the references below and try different flows using the playground
References
Which oauth2 flow should I use
OAuth2
PKCE in more depth
My advice is to start with the data, which is the deeper area of OAuth.
USE AN AUTHORIZATION SERVER
This will enable you to keep your code simple. It will also handle Google / Facebook and many other forms of authentication for you, with zero impact on your code. The Curity Community Edition is a free and developer friendly option, though there are others. eg Keycloak, Ory Hydra.
PROTECT DATA
OAuth primarily gives you modern ways to protect data. Use scopes and claims to protect data across multiple microservices in a zero trust manner while securely maintaining user context. You will also need to manage joining identity and business data.
IMPLEMENT UI FLOWS CORRECTLY
Mobile apps use the AppAuth pattern. The current best practice for browser based apps is a Backend for Frontend approach. Both of these are tricky.
KEEP CODE STANDARDS BASED
All of the above Curity resources are based on OAuth related standards. If followed your apps will stay simple, with portable code, that can also work with other providers.
OAuth is very architectural though, and the best designs take time to learn, but you can learn the intricacies gradually. Our IAM Primer is a good starting point.

SPA + API OAuth flow, what to use?

We are struggling about what OAuth flow to use with our app.
We are using Node.JS as our back-end API and Angular as our front-end.
What we want to do is, log in an user, retrieve an access token and use this access token in order to make some API requests (basic POST/GET/PUT/DELETE).
A user (still unknown at this point) lands on a login form OR a register form. He proceeds to the login or the registration.
Once logged he's on his dashboard with an access token, now every time he wants to interact with the API he must use his access token in order to interoperate with the back-end. (which is a classical behavior).
This seems easy, we wanted to use the Implicit Flow but we need a client_id in order to retrieve an access token and the user is still unknown at this point.
We then thought about using the Password Grant flow because our users will have a login/password, but OAuth specs. recommend not to use it except we have no choice.
I know this is a super basic question but what kind of OAuth flow do you recommend with this ? If we have no choice we'll just use the Password Grant but wanted to explore every single solution.
Thanks !
I'm not sure I understand what you mean by:
we wanted to use the Implicit Flow but we need a
client_id in order to retrieve an access token and the user is still
unknown at this point.
If you are using Oauth2.0s implicit flow then your angular app should be registered as a public client with the authorisation server - that process would give you a unique client_id for your angular app. Your angular app can then use the implicit grant and redirect the unknown user to the authorisation server's authorise endpoint passing along in the querystring its client_id along with its redirect_uri and various other things.
The authorise endpoint will prompt the user to register/login to the identity provider and consent to the scopes your Angular app requests.
Once the user logs in (or registers), the authorisation server should then redirect back to your Angular app's registered redirect_uri passing an access_token in the hash-segment of the returned http querystring.
Sorry, I know that I'm not answering directly to your question.
But did you consider using an authentification backend as Auth0 ?
Security is key and OAuth is a complex protocol.
Auth0 give you every thing you need to manage users, use a social identity provider, and integration with Angular.

Should my app issue it's own access tokens, when using external oauth2 provider (facebook)?

I would like to give the users a possibility to login with some external oauth2 provider (facebook) in my app. The client's part is running on mobile device in a native app.
I am not sure which of the approaches below should I prefer ?
Should the client send the user's access token by facebook with each request ? At each request backend asks facebook to validate the access token. Based on the validation's result, backend performs authorization and return corresponding result to the client.
Should the backend ask facebook to validate the access token only at user logon, then issue its own access token, return the access token back to the client and client will use this access token at making requests to the server to avoid contacting facebook at each request ?
I have read some questions about how to implement the auth with facebook and most of the devs are using B, but I haven't seen any explanation why is it good/bad to use A ?
What I see as benefits of the solutions:
backend doesn't need to care about issuing, refreshing, validating access tokens since this is done only by facebook's authorization servers.
this solution seems to be more effective, since it does not require to connect to facebook at each request.
Security tokens issued by Facebook are signed with a digital signature. The API server only needs access to the public key to validate the signature. There's no need at all to contact Facebook after the user authenticates.
A reason to issue your own tokens after the user signed in with Facebook could be to add claims to the token. But obviously having your own authorization server comes at a cost. It's up to you to weigh the pros and cons.
If you do decide to have your own authorization server, make sure not to write your own! There are open source options like Thinktecture IdentityServer.
I will vote for option B and here is my explanation,
Your API must authorise the request every time with some auth token , which cannot be external provider token, in such case anyone with an access token (eg: other developers) of other provider can access your api, basically there is no auth here.
When your sever issue access token, it's easy to validate and when needed could be revoked easily (eg: on password reset)
While authenticating , your server has fully control over issuing access token , so the validation is made only once and doesn't have to do every time while calling the API.

Is OAuth 2.0 just for authorizing applications and not users?

When I first heard of OAuth was in ASP.NET Web API applications and I've used it as means of authorizing users to access resources on a RESTful API. By the time I felt I was using it right, but right now I think I got the idea wrong and this is the subject of this question.
At the time, I used OAuth in the following way: on the API there was a token endpoint to issue tokens. I created a login page in a SPA and posted the username and password to the token endpoint with a grant type password and the token that came back I started sending with each request.
When the request had the Authorization: Bearer [token] header with a token issued with some username on the login page I understood the request was being done "with the user logged in" and so I could authorize access to resources.
Studying OAuth deeper my conclusion is that my usage of OAuth was completely mistaken.
My understanding now is that OAuth is just for authorizing applications and not users. In that case when we make a request with the Authorization: Bearer [token] header we are saying identifiying to the resource server that the client making the request has been authorized to access the resource, but we are not saying anything about the user?
In that case, with OAuth we just can say what resources client applications can access but we have no information to decide whether the user is allowed or not to the resource? Because of that my initial usage is truly wrong right?
OAuth 2.0 can be used for authorizing a client (an application) to call an API. This authorization is done via an authorization grant.
The grant is given by the resource owner in the case of authorization code, implicit and resource owner password grant through authentication of the user with the authorization server and clicking accept on a consent screen.
The first two grant flows are interactive and require an agent that understands HTTP (redirection) responses.
Most authorization servers also support the client credentials grant. In this case, there's no user involved and a pre-registered client (application) uses its own client-id and secret to authenticate with the authorization server.
Which grant flow to use depends on the type of client you use and who owns the resource the client needs to access. I describe the differences in my answer here.

Using OAuth instead of Basic authentication?

We have a web service, which currently uses Basic Auth over https to authenticate user requests. We also have a website which uses the service, and a native Windows client, which also uses the web service. I've read about OAuth, and it seems like it's always used for giving or getting access to external resources, i.e. delegation, but I'm trying to understand if it's a replacement for Basic Auth.
I'm not quite sure how all the parts fit together. Do you use Basic over https to the website to retrieve a secret and then have the javascript which is making requests to the REST services authenticate to the web service using OAuth instead of Basic?
It seems that at some point the user needs to enter their username and password into a form. I'm not sure what typically happens next. Is this even a use case for OAuth?
If you have local database accounts for the users (Resource owners) then you can replace the basic authentication with the one of OAuth flow named "Resource Owner Password Credentials" flow.
It is very simple flow where you issue HTTP post to an end point specified in your HTTP server usually named /token The content-type for this HTTP Post action is x-www-form-urlencoded, so the post body will contain something like this grant_type=password&username=Taiseer&password=SuperPass
One the request is sent to the /token end point the server will validate the user credentials against your database store, and if all is valid it should generate a token (signed string) which contains all the claims for this resource owner (user). Then your client application should present this token in the Authorization header with each call to any protected end point using bearer scheme.
This token expires after certain period and you can configure this from the AuthZ server. You can read my detailed blog post Token Based Authentication to get more details.

Resources