What's the difference between passport and oauth? - node.js

I'm trying to build an authentication service with express.js, but I didn't catch the idea of authentication modules yet.
What's difference between passport and oauth middleware? Are they dependent of each other? Is useless to have the BearerStrategy without an oauth server to generate tokens to the BearerStrategy validate? Am I on the right way?
I've read about oAuth2 and Its authentication flow, but I'm still lost with this uncoupled code.
I'm trying to build the Resourse Owner Password authentication with refresh token for my AngularJS frontend communicating with the backend API, and I'm facing with many combinations of password.js strategies (Basic, Bearer, ClientPassword) with oauth2orize on the other side.
So, I'd like to know a very simple explanation of how authentication works on NodeJS. At really I know that Express is not inventing a new way of how authentication works, but the modules are too unobtrusive that I need to understand the base of how It works to achieve them working together.

Passport is authentication middleware.
OAuth is authorization middleware.
To understand the difference:
Authentication is the process of ascertaining that somebody really is who he claims to be.
Authorization refers to rules that determine who is allowed to do what. E.g. Bob may be authorized to create and delete databases, while Bobbette is only authorized to read.
In other words. Authentication is your username + password. Authorization is what you're allowed to do.
Passport will allow you to authenticate the user before allowing access to your API. It does not (directly, it's possible) allow to check if a user is allowed to perform an action after authentication.
Check this Wikipedia for more on Authentication vs Authorization.
What OAuth does that Passport doesn't, is that it allows users to grant a service access to their personal information. It also allows users to allow or disallow certain privilages (scopes in OAuth).
Do note that there are a lot of OAuth flavors. The most common is the version with authorization grant types seen when authorizing with Facebook or Google. But there are many others including the Resource Owner Password strategy you mentioned.

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.

Correct strategy for auth in an API

I want to design a GraphQL API. This API would be used by some browser apps and also open to be used directly for people that want to create their own scripts/generate reports etc. The API would rely on a third party app supporting Oauth Openid Connect (okta) for user and role management. It would be written in Django.
Because JWT is a recommended way of protecting GraphQL APIs and also because OIDC uses JWT tokens. I thought of a simple way, where the API would simply accept the JWT tokens issued by okta. This works, but I see a lot of latency when API is asking okta validate the token (this latency might be smaller in production, because I'm testing on a free trial auth0 instead of production okta). So I think that maybe my API should issue its own JWT tokens. I can think of three strategies here:
Leave it as is – only use the OIDC JWTs.
Introduce a login mutation or a login REST endpoint, that would accept OIDC above and issue JWTs that can be used for all other operations.
As above, but also allow the direct use of okta's JWTs (I'm not sure if I can implement it with Django's auth system, so that if a token is recognised, the OIDC is not called).
Which of these three is the correct (and maybe intended by the OIDC designers) way to protect my API?
JWT token doesn't need to be validated by Okta (generally by IdP). You just need to get used public key (it can be found as jwks url in discovery response) and then can you can verify signatures without any IdP call.
IMHO you can get 2-4k validations/sec easily.

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.

Security concerns about using Facebook implicit token for server side resource server OAuth2 authentication

I have poured over the OAuth2 docs and seen how the Facebook Javascript SDK uses Implicit Grant.
I am building a ReactJs application, which communicates with a PHP-Symfony API.
What I want to do is offer the "Login with Facebook" option on the frontend.
What I need on my PHP server is the Facebook user id and email and other data of the user so I can initially create a user record for them in my DB and then on returning visit, use the auth token to get that info again on the server and use it to match it to existing records and log the user in.
We have done this previously using the Authorization Code Grant method to redirect the frontend to our server, then to facebook and then back to us with the auth code. We then use that on the server with our Secret Key to get the Access Token and get the user info directly from Facebook to our server and then authenticate the user.
The redirection is a bit of a pain for a single page application.
Facebook's Javascript SDK handles a lot of that automatically, but uses Implicit Grant, returning an Access Token directly to the frontend.
What I want to know is, can I just send that Access Token to my server to do the same type of authentication that I did before? Or is that a massive security hole that I am opening up?
Comparing the two, the Auth Code from the Authorization Code Grant flow also goes via the frontend, but very quickly, not directly to JavaScript and is much shorter lived. So it feels much more secure.
If intercepted in time and with matching state, it could be used to authenticate someone on our server, but not access someone's Facebook data directly.
Reusing the frontend Access Token from the Implicit Grant flow feels like it is open to messing with, but I can't put my finger on the exact scenario that would make it more vulnerable to attack. The token would potentially give people access to not only authenticating on our server but also to accessing people's Facebook info.
So this is ultimately a question of best practice and security.
We think that we should be able to implement our own popout window that does the Authorization Code Grant style flow and retrieves our server cookie which can then be used by the page that spawned it, but it is going to be tricky and most of the work seems to be done for the Implicit Grant method, if it is safe to use as we intend to use it.
Best Practices AND According to the RFC 6749
However, this convenience should be weighed against the security
implications of using implicit grants, such as those described in
Sections 10.3 and 10.16, especially when the authorization code
grant type is available.

OAuth 2.0 authentication for own mobile client

I am developing an app using node.js which will also have an mobile client. I am looking to make the authentication using OAuth 2.0. Is there any good module which allows me to have OAuth 2.0 authentication server?
I looked at a subsidiary module of Passport "OAuth2orize". I found it quite good enough, but the real problem was understanding how it will work for my own app (the example and docs specify about third party authorisation).
Basically what I want is that the client logs in with client id, user's username, user's password and there by I hand him a token after verifying the above 3 things. But the problem with Oauth2orize is that there there are redirect URI and all which is confusing me a lot.
Please help me know as to how can i achieve this using Oauth2rize or any other really good module. Or If its easy enough I can also roll my own, but will that be a good idea regarding security ??
What you are looking for is the Resource Owner Password Credentials flow. As you've seen, the examples for oauth2 do not include functionality that supports this flow. In fact the examples only cover the Authorization Code flow.
It should end up being fairly easy to implement. All you need to do is accept a request that contains the information you are looking for (and authorize it) and create a token in your token database and return it. As long as you use the same token database that the rest of oauth2orize is using, it should work just fine. See: Passing Trusted Client Information with oAuth2orize for the "Resource Owner Password Flow" where that is exactly what is suggested.
Correction:
The all-grants example of oauth2orize supports the Implicit flow as well as Authorization Code flow.

Resources