OpenID Connect /Node /React - reactjs

There is a lot of examples how to implement OpenID Connect auth. in Node - code grant (+ client password).
There is a lot of examples how to implement OpenID in React (SPA) - code grant with PKCE
Even I know that PKCE it's rather secure, however I feel bad to relegate authentication solely on client side.
Every React SPA has backend (at least it should be hosted somewhere).
I want to have server side in Node (Express) to securely save client password and make all heavy lifting with Identity Server and
React for front-end.
As I already said there is a lot of examples of "Node (Express) with template engines" for authentication.
But I want to use React as "template engine".
So, I am looking for full and correct implementation of it. Meanwhile I cannot find it.
Can anybody help me with it - to find an example?

You need some actual protection in the SPA / browser though, and the 2 common options are:
Plug in OIDC Client Library to do the heavy lifting, so that you don't write much security code yourself. This library runs a number of strict security checks before accepting tokens.
Use a proxying solution that results in your SPA getting a cookie.
For an SPA this tends to be a more of a home grown solution rather than a standards based one
RESOURCES OF MINE FOR OPTION 1
SPA Security Code
Explanatory Notes
FOR OPTION 2
You could use the Open Id Client Node JS Library server side, and follow it's guidance.

I've found 2 solution on the Internet.
The First :
Implement social authentication with React + RESTful API
On the frontend, get the 3rd party app’s login popup to appear.
(Still on the frontend) Grab the authentication token the 3rd party app returns after >agreeing to login.
(Yep, still frontend) Send that token to the backend as part of the body of your >request. (I like to use Blobs, but that’s just me.)
On the backend, verify the token.
If the token is authentic, you will receive the user as part of the verification >response (at least that’s the case with Passport.js, which we’ll be using).
Save the user’s data to your database.
Return a JWT token to the frontend. What you do with that token is out of scope for >this tutorial, but it should probably be used to authenticate each of the logged in >user’s actions.
Very well explained, with github working example social-auth-example
It's only for social authentications, but I think no problem to make something more general or at least to add my OpenID Connect Auth. provider.
The second example:
React Authentication with Twitter, Google, Facebook and Github
This approach uses socket.io. Very interesting.
P.S.
So, I need to figure out what solution is more secure and if there any security breaches.
Not easy task to do. It's so pity, there is no standard flow for my problem. I can find 1000 reasons why it's better to make all heavy lifting on back-end and not to rely on OIDC Client Library. The first reason is my boss :)

Related

OAuth client secrets in React apps

I have been trying to learn about OAuth2 and OpenID Connect and this article was the most helpful so far:
https://developer.okta.com/blog/2019/10/21/illustrated-guide-to-oauth-and-oidc
But it made me wonder:
If the "client secret" is supposed to be a secret (duh) between the Client and the Authorization Server, and the Resourse Owner is never supposed to know about it... how does this work in things like React, where the Client is run directly in the "client-side" (redundant terminology...).
I am guessing that you are not supposed to distribute your "client secret" publicly, so you clearly cannot deliver it along with your app.
A React SPA is a 'public client' and does not have a client secret, since, as you indicate, it cannot. be stored securely in a browser.
For React you would use Authorization Code Flow + PKCE to sign users in. This involves use of a secret that is generated at runtime - as well as an end user providing credentials.
It is also possible (and recommended in 2021) to proxy OAuth requests that involve tokens via a Back End for Front End API.
This allows the API to attach a client secret and in effect this upgrades the SPA to a 'confidential client'.
FURTHER INFO
I think more libraries will become available that implement this type of security in 2021. See also this video.

React SPA with oidc-client and client secret

I'm building a React SPA on top of a ASP.NET Core API and I want to authenticate with OIDC. Grant type is authorization code and the client does have a client secret.
Since we will be using a client secret, the authorization step that involves the secret has to go through a proxy that we control.
Is this doable in a React SPA with oidc-client?
If the secret is in the client, it's not a secret. :)
Secrets are for server-server authentication, because the secret is secure on a server (we hope so, anyway) and the API granting access has a whitelist of consumers it's granted access to use the secret.
For a SPA, if you're talking about allowing an app to use an API, I believe you're limited to using a CORS whitelist. If you're talking about a user accessing the API via the client, then you're looking at access codes and usernames/password.
PROBLEM
You have a blocking issue with the authentication system, or with usability or getting security to an acceptable level. In your case there is no PKCE support.
PROXYING SOLUTION
Use oidc-client which will add PKCE parameters and your SPA security supports the latest standards.
The client secret will come into play during the authorization code grant and refresh token grant messages.
Messages can be adapted server side to remove PKCE and use a client secret instead. It is quite a complex solution though and not everyone will like it.
It requires a SameSite cookie issued by the web domain. In my case I used an AWS lambda edge function that runs within a CloudFront content delivery network.
WHY DO IT THIS WAY?
In order to fit into an SPA architecture and meet wider goals in areas such as usability, coding model, mobile integration and global web performance. Depends if you feel it is worth the effort.
LINKS
Architecture Goals
Design Pattern
Code Sample you can run
Online AWS SPA
Proxying details

Resource-owner password credentials grant suitability for first-party login

I have a public-facing application that uses ASP.NET Core Identity to store first-party logins, and no intention of using third-party IdPs like Facebook or Google. I want to build the front-end in React, and the application comprises an API fronting a couple of back-end services to which I'll need to forward JWTs for authorisation.
The plan so far is to use Identity Server 4 as the IdP for the project, backing it into the ASP.NET Core Identity data stores.
Current guidance is to use Authorization Code Flow with PKCE, which would require redirection to the IdP, two sets of styling etc.
In this scenario, where there is no possibility of a third-party IdP, is Resource Owner Password Grant still highly discouraged? On the face of it, it gives a neater experience:
User populates React-based login page
XHR POST to IdP with credentials (modulo an MFA challenge)
IdP returns an access token, React app subsequently uses that for future requests to the API
What issues will I introduce by pursuing the ROPC grant in this specific situation, vs accepting the need and duplication involved in a redirect-based flow to the IdP?
AMOUNT OF WORK
This is one of the big issues. As well as a login screen you'll have to make sure other areas such as Forget Password also work. If you build a second app you'll need to make it work there also.
EXTENSIBILITY
This article summarises problem areas. One of these is no scope to ever extend login solutions.
SECURITY
Token refresh does not (usually) work with ROPG, which leads to long lived access tokens and other complexity. Also, with OAuth it is recommended that the app never sees credentials.
From a security viewpoint it looks more modern to redirect the user - all the big providers do it - eg Google, Microsoft.
BRIDGING SOLUTION
As you say, if the password is private to your app it may not be the worst thing in the world. Capturing a user's Google password in your app would be a bad thing though.
ROPG has its uses but does not have much of a future - it is deprecated in OAuth 2.1 and providers will be getting rid of it. So I would also recommend what LalitaCode suggests ..
You can create a React based Identity Server login page for Authorization Code flow with PKCE instead of using MVC UI if you want. It is just extra work and complicated. I would recommend you just style the Identity Server MVC UI to look exactly like your frontend SPA. This is the simplest way and the path I took when I did a project with Identity Server(with Angular as front end).

How should I setup auth in a nodejs app?

I am currently developing a small application with a couple of endpoints in nodejs and an angularjs frontend.
At the moment I have an endpoint for users and another one for events. The thing is, I was thinking of making all the GET methods require auth, so that someone that isn't logged in can't access the system, for that I thought of using PassportJS.
Anyways, my question/s would be the following:
What auth strategy should I use? Basic, OAuth or another? Why would that be? I mean, I understand how their flow works, but I don't know why one or another would be appropiate for my app.
Should the endpoints require auth or should it check cookies/token or something else in the session? I'm completely new to this, so I don't even know if this question makes sense.
In any case, I would appreciate any overall insight in the topic since I don't have any experience in developing applications with auth and security.
Thanks!
You have to provide more details about your authentication needs in order for someone to give you a definitive answer to this broad question.
Based on your question, one can assume you don't have any requirements though, therefore I could suggest JWT (JSON Web Tokens - https://jwt.io/)
There are nodejs libraries that can help you create, decode, verify JWT tokens. (such as jsonwebtoken). You can find more details about it on github.
Once someone is logged in, you could pass this generated token back to the client which could store it in the browser's session.
The token can be used in subsequent requests by appending it in the request header.
On the server side, you can add a custom auth middleware to the routes that require authentication, which will verify the token's validity and call the next middleware for the current route.

Oauth social login using MEAN.js Restful sessionless API backend

I'm developing a Restful API using MEAN.js, which will be consumed by an AngularJS Web site and Phonegap Mobile Apps.
I'd like the user to be able to create an account and/or login using Faceboo, Google and Twitter.
I'm trying to use the same sample code that comes with MEAN.js seed application, but with the Node side of it, on port 3000 serving only the API, and the web site running on another server (currently on port 9000).
I','ve already implemented Token authentication using a Passport custom Local strategy, which generates a token, and the Bearer Strategy to autheticate API calls.
But I'm having problems with social login, to link social accounts to existing users.
From the Angular Client I call an api endpoint that redirects the user to the oauth provider (e.g. Twitter). When the user comes back, my serve has no knowledge of the logged user, since I'm not using sessions anymore.
I've tried to return the provider token to the client, but have problems parsing the anguler url. Then I coded another page outside angular that receives the provider token and calls an api endpoint sending the oauth token and the token issued by my api. It worked for Google, but not for Twitter. It seems twitter needs a session.
Anyway, what is the best approach to achieve what I want? How can I make this work?
Since your using Angularjs, take a look at this Angularjs library https://github.com/sahat/satellizer. The library pretty much opens up an oauth popup and checks the popup url for tokens. You can easily replicate the approach or just use this library. It works with a few social media providers like Twitter and its easy to add more.
I was in need of the same thing and so I set out to create my own. It's still in development but should give you a good start. Feel free to create a pull request and help to make it better. Maybe we can eventually merge it into their codebase.
https://github.com/elliottross23/MeanJsSocialLoginTokenAuth

Resources