OAuth2 client credentials - node.js

So right now I'm implementing oauth2 in my server, but I just want to support the client_credentials grant. The thing is, the node-oauth2-server says that supports this type of grant, and I pretty much debugged the whole library, and there are some things that doesn't make sense to me.
As far as I understand, the client_credentials grant should work like this:
An internal request should be made to generate the client_id and client_secret for the client, this is the only time we will get the client_secret and we should give this to our client
The client_id should be stored in database with any extra data (like the account id associated or something like this) and a hash of client_secret so we can later validate it
The client sends a request to the server including the client_id and client_secret
The server should then generate an access token (in my case I will be using JWT) and return from the request. We also need to store this token in database so we can revoke the permission if needed
The client must use this access token in future requests to access resources from server, and the server will validate on each request if the token is valid (didn't expire, didn't lose permissions, etc)
I may be wrong about this, but this is what I need and this exactly what C# Identity does and it is explained here.
In my case I'm working with nodejs. Actually is a NestJS project, so I was trying to use this lib which is basically a wrapper for node-oauth2-server, and if you take a look inside node-oauth2-server, looks like they only support authorization codes, this is because the AuthorizeHandler.handle() always returns an authorization code and AuthenticateHandler.handle() always expects the authorization code and returns the access token. Basically I need to call the AuthenticateHandler.handle() but instead of checking the authorization code, I must pass and check the client_id and client_secret.
This is a recent issue which has the exact same issue than me: https://github.com/oauthjs/node-oauth2-server/issues/552
So, first, I want to confirm that I'm right and this lib have this implemented in a bad way, and second, is there any other nodejs lib that has client_credentials built in?

As you've mentioned that it doesn't support client_credentials grant at the moment, you can still utilize the authorization code flow grant type internally to get the access token.
Prepare client_credentials grant type request and submit to server.
Map this request to authorization code flow with additional
attributes require for the authorization code flow.
Submit the request to Authorization server.
Get the code from response.
Prepare the token exchange call with the oauth code.
Get the access_token.
Return the token in response to client_credentials call.

Related

Authentication with JWT in React and Node-Express using Github OAuth

I have been trying to implement Google and Github OAuth authentication in one of my projects which uses React on the client side and NodeJS-Express on the backend. After going through dozens of articles and several Youtube videos later, here's what I have discovered about OAuth.
There are two main flows in OAuth. Authorization Code Grant Flow and Implicit Flow. To be on the same page, I would elaborate what I understood about both of these flows in short:
Authorization Code Grant Flow : User(resource owner) clicks on Login with Google/Github and is then redirected to the consent screen. Once they give consent, user(resource owner) is redirected back to the callback_url with a authorization_code in the URL query parameter. The authorization code is then send to the backend server. The server then makes a request to the authorization server of the OAuth provider along with the client_id,client_secret and the authorization code and then receives a access_token as well as a refresh_token required to access the resource server.
Implicit Flow : It is sort of a hacky way that was proposed back in the day for Single Page Applications as CORS wasn't properly implemented in all the browsers. Here the Single Page Application is given the access_token once the resource owner has given consent to the OAuth provider and it is now the duty of the SPA to store the access_token in a protected manner. However, since browsers aren't really trustworthy, and CORS is a real thing now, the Implicit flow is not really recommended anymore.If someone wants to implement the Implicit FLow, PKCE (Proof Key for Code Exchange) is sort of the standard now.
What I tried to implement
I decided to go ahead with Authorization Code Grant Flow as it seemed the most secure to me and also I have a backend server to handle the authorization code exchange.
Here is what most people suggest in order to implement Authorization Code Grant Flow with React.
Render a link like this.
<a href='http://localhost:8000/auth'>Login With Github</a>
Now handle this endpoint in the backend
app.get('/auth',(req,res)=>{
res.redirect(githubOAuthConsentScreenURL)
})
Now handle the redirect_uri in the backend and make a post request to the authorization server to get a access_token
app.get('/auth/callback',(req,res)=>{
//Extract the authorization code from query params and make a POST request to get back the access_token
})
Passport JS also implements this approach which is handling the callback url on the server.
Here is what I thought of doing:
Handle the callback URL on client side i.e. with React. Extract the authorization code from the parameters and then make a XHR call to the server with it. The server will now exchange the authorization code for an access_token and make a request to get the user's profile data. If everything succeeds, the Express backend will return a short lived access_token and a long lived refresh_token which will then be used by the React application to access the REST API.
My question here is : Which method is correct and the standard way to do authentication, handling the callback_url on the server or on the client side?. The method I propose over here seems more logical to me. Does my method have any security flaws compared to the other one? Am I missing something?
Other things that I have confusions about :
How is OAuth vulnerable to CSRF? From what I read, the state parameter can be used to protect the OAuth flow against CSRF. However, if I am redirecting the user from my backend server and then handling the callback_url in the server as well, how do I remember the state variable apart from storing it in some sort of session/db. Is it not more logical to redirect the user from the browser? Then the state parameter can be stored in the localStorage and can be matched later during the callback.
Also, I am implementing a short lived access_token and a long lived refresh_token for authentication and storing both the tokens as httpOnly cookie. If my access_token is stored as a httpOnly cookie, then how do I know if I am logged in or not and persist the state in React. One solution (proposed by Ben Awad in this video) was to query for the user during initial load and if the query succeeds, store the state (maybe in Redux) and then conditionally render the routes.
Is this the correct way of doing this? If not what is the standard manner that is followed by React applications which are actually in production? Again, am I missing something here?
Please Note : I am pretty new to authentication, would appreciate all the help and detailed explanations.

SPA + API + OIDC: How to authenticate an API caller when it's only providing an ACCESS token?

Let's say you are developing a client side JavaScript SPA app (Angular), a backend API for this app (ASP.NET Core in my case) and you use an identity provider that implements Open ID Connect protocol (I'm using IdentityServer4).
Apparently the recommended way for securing the app is to use the OIDC implicit flow between the JavaScript app and the identity provider and if successful the JavaScript app gets an id token and an access token.
Now according to this documentation the JavaScript app is supposed to pass the access token in the headers whenever it calls the API. And I'm not sure what purpose does the id token serve in this case (besides customizing the UI in your JavaScript app)?
But this is the confusing part: The documentation also says you should never use the access token for authentication. But that is the token that my API receives in the request headers, how can it authenticate the user then? If my API receives Post(newRecord), and the API needs to internally fix some audit information on newRecord (i.e newRecord.CreatedBy = CurrentUsername), how can it do that without authenticating the caller??
I think I'm missing a piece of the puzzle. Please any help is deeply appreciated.
Short answer/suggestion
Use Access Token to access API endpoints. From API endpoints, you must use token introspection endpoint to validate token validity (active state) as well as obtain subject who authenticated at authorization server. IdentityServer provide support for this. Documentation is available from here.
Explanation
ID token is intended to be used by receiving client. It will allow your client to authenticate the end user and provide user specific customizations. This is the whole purpose of OpenID Connect (OIDC). On the other hand OAuth 2.0 provide an authorization framework. It replaces user credentials with access tokens, thus improving API access security (compared to basic authentication and storing user credentials everywhere). Hence OIDC is built on top of OAuth 2.0, you get both ID Token and Access token with OIDC flow.
But as you have figured out (and mentioned before), ID token is intended for client. There are could be exceptional cases where ID token get passed between client and a server. This is mainly when both are controlled by same party. But the access token is the key to access API endpoints, correctly.
Access tokens can be an opaque string or JWT. When it's a JWT, API can read and understand the token (self-contained). When it's opaque, only way to validate token at API endpoint is to use token introspection endpoint. If API can validate token validity, then it could grant access (authorize) request. Furthermore, if user details (subject) are available (through JWT or as introspection response), then user specific checks can be executed. This further extends to token scope values. But at the end of the day, you are authorizing the API request and not authenticating the user at API endpoint. That's the highlight. Hope things are clear now.!

Is Oauth2 authorization code bound with the client id?

I tried to login with two separate website, both using "login with Google". Intercepted the auth code from the 1st site, and exchange it with the auto code to the 2nd site. Neither site will let me login. I remember in RFC6749 it is not specified that the auth code to be bound with any identity, is it implemented so to increase security?
This is indeed part of OAuth2.0 security:
Exchange the Authorization Code for an Access Token
We’re about ready to wrap up the flow. Now that the application has
the authorization code, it can use that to get an access token.
The application makes a POST request to the service’s token endpoint
with the following parameters:
grant_type=authorization_code - This tells the token endpoint that the
application is using the Authorization Code grant type.
code - The
application includes the authorization code it was given in the
redirect.
redirect_uri - The same redirect URI that was used when
requesting the code. Some APIs don’t require this parameter, so you’ll
need to double check the documentation of the particular API you’re
accessing.
client_id - The application’s client ID.
client_secret -
The application’s client secret. This ensures that the request to get
the access token is made only from the application, and not from a
potential attacker that may have intercepted the authorization code.
from https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type#exchange-the-authorization-code-for-an-access-token
Short answer : Authorization code is bound to the client it was issued
This is strictly enforced by the RFC6749 and stated in 4.1.3. Access Token Request section. Also, it is one of many checkes authorization server perform to validate a token request. Specification has following stated,
The authorization server MUST:
o ensure that the authorization code was issued to the authenticated
confidential client, or if the client is public, ensure that the code
was issued to "client_id" in the request
So when authorization server will cross check authorization code against client id or client credentials depending on client type.
Furthermore, authorization code is a temporary secret which must not be exposed to other parties. This is highlighted in security consideration's 10.5. Authorization Codes section.

OAuth authentication authorization

i am totally confused about the usage of OAuth and i am not sure how to use oauth for my szenario. At the moment i use a "pure" JWT approach which looks like that:
Client (JavaScript Application) send login and password to my Rest-Endpoint (Server (Java)).
Server validate user informationen, read / generate some user roles and wrap it in a JWT Token (with a secret)
Server send JWT Token back to client
Client will perform additional Rest-Calls with Authorizationen Header
Server validates Token with private secret and grand access based on roles/user
Now i think about the usage of OAuth but i am confused how to use it to realize the szenario.
I registered an application at "auth0".
I use a JS library to redirect to the login process of auth0, login via auth0 account and consume the id_token and access_token
= i can send the id_token (JWT with RSA256) to my rest api, validate it with the public certificate and can extract some user information
but:
a) i have read that i should not use the id_token to access my api. Instead i should use the access_token (which is not in JWT format and will not give me any information about the user) and use the access_token to query for the user information? That whould be the case for every request?!
b) i don't see the point where the user roles come into play. When i have some operations (rest endpoints) which are only allowed for "admins" or "customers". I don't see any possibility to define them.
You see i am a little bit confused, i hope somebody can clarify all the things.
Thanks a lot
Chris
a) Both tokens you use should be in JWT format and you should use access_token for authenticated queries. The access_token not necessarily contains information about the user, so on server side you usually can decide only that the token is emitted by the token service and is valid. If all these checks are passed, you should accept it as an authenticated user.
b) User roles can be placed into the access_token's payload section as an additive claim (e.g. role=admin,datawriter or role=customer,listreader) like many other things.
I hope it helps.
a) Sounds like you are getting an opaque access_token back and not a JWT. You'll need to create an API in Auth0 (similar to the application/client you already created). Then you pass that identifier in the audience parameter when you authenticate. Then you should get a JWT back, and that will have a sub parameter which is the Auth0 ID of the user, which can help you identify who the user is. I believe you could also use Auth0 rules if you need to put more identification info into the token. See here for a full explanation of the opaque vs. JWT access token: https://auth0.com/docs/tokens/access-token
b) Roles are tricky. I believe Auth0 would suggest that you create scopes on your API, and then request the scopes needed during login. Auth0 Rules would then be used as a sort of "glue", to adjust scopes that were requested but not permitted for the authenticated user. They also have an Authorization Extension you can use to help facilitate some of this. Another option could be storing role info in the user metadata, and using rules to put that info into the token. Finally, the option we chose was to not use Auth0 to define our roles. We let Auth0 authenticate, and once authenticated we check access in our system for the authorization side of things. Lots of options.

Difference between open id connect basic client and imlicit client profile

Hi I am working with Open Id Connect protocol for authentication scheme. I just want to know what is the exact difference between basic client and implicit client scenario's in Open Id Connect.
The difference is that basic client uses OAuth2 Authorization code flow, while Implicit client uses OAuth2 implicit flow.
You can find the differences between these two flow in OAuth2 RFC (https://www.rfc-editor.org/rfc/rfc6749), but basically:
Authorization code flow is composed by two requests and responses. The first request (response_type=code) asks for a authorization code. The provider responses (if authorizated) with a authorization code. Then a second request is made (response_type=token) sending this code and asking for the access token. This flow is used from server-side.
Implicit flow is composed by one request and response. The request (reponse_type=token) asks directly for the access token, and the response injects the access token into the redirection URL. This flow is used form client-side (script).
Hope this help!

Resources