Difference between open id connect basic client and imlicit client profile - security

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!

Related

OAuth2 client credentials

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.

Node.js Cognito sends # before token in URL

I have a cognito setup (with only Implicit Grant enabled) and have http://localhost:8000/login as callback login URL specified.
I have a backend side(Node.js) which expects GET request on /login endpoint and I plan to parse/verify token there.
When login is done it redirects me to http://localhost:8000/login#id_token=...
The problem is that as I know the part of the URL starting with the # symbol is never sent to the server. So how can I receive the token from Node.js side?
You shouldn’t be using implicit flow. It’s an outdated and insecure feature of OAuth. The token is passed in the hash specifically because it is meant for client side applications. Since you have a nodejs backend as your client you should be going through a authorization code (with PKCE) grant.
What is the response type used? Is it response_type=id_token? In that case, in order to have it sent to a backend for a simple OIDC Login flow you have two options
add response_mode=form_post, which will result in the IdP triggering a self submitting POST form to your redirect_uri
add a "re-post" handler to your GET redirect_uri that will read the fragment portion and POST it to your backend.
Each of the two has its benefits as well as drawbacks.

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.

OAuth 2.0 - why consent screen doesn't require client secret?

I'm learning OAuth 2.0. When using authorization code flow, it's enough to pass client ID. Does it mean that, in theory, an attacker can generate multiple authorization codes easily?
What was the reason why the consent screen doesn't use client secret? It's secure, as authorization server should deliver HTTPS connection.
Is it only for simplicity, to allow linking on client-side, like this?
Login with Koala Auth
No, according to RFC-6749 section 1.3.1, the user is authenticated by the Authorization Server before an authorization code is given back. Therefore, the client ID is not the only piece of data the is needed to get an authorization code.
This is not because the resource owner redirects the user-agent to the authorization server that this authorization server will give back an authorization code: the user-agent must complete an authentication step with a valid user, before the authorization code is given back to the resource owner.

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.

Resources