Authentication and Authorization in React app - reactjs

In a .NET app I can add authentication and authorization using web.config and/or IIS. I can also use [Authorize (Roles = "RoleABC")] in a MVC app's controller or action. And even extend the AuthorizationAttribute
I'm looking into creating a React app for intranet use, and reading these tutorials (ReactJS and MS), but can't find authentication/authorization details.
Even though the app will be Single Page App, I still would like to authenticate and authorize users for certain options within the app, just like I can do in MVC app.
Is the only option to do that way is creating Blazor app instead?

For authentication and authorization, you should use auth tokens (like JWT). Your backend should create an auth token when a client logs in to the system and sends it to the client. Your server also should send the authenticated user information to the client (react app) so that you can render correct pages according to the user type. For example, you can render the admin page for an admin type of user, and the guest page for a guest type of user. You can save this user data as JSON in Redux. Hence you can access the user data from any component of your react. Also, in your backend, you must restrict the endpoints according to the auth token which is sent by the client. In the backend of my app, I follow the below steps:
Authentication check -> Authorization check -> controller (endpoint) -> result

React isn't opinionated on this, so it's up to you to design the implementation. A basic way to do this is:
Log in and obtain an authorized JWT token from the backend and include the account ID when you sign it
Store the JWT token in localStorage, store the account info in Redux
Conditionally limit routes based on account info (ie. admin group) on the front end
Have every auth-required API call include the JWT token in the x-auth-token header, then on the backend use middleware to check if it's still valid. You can then also decode the account ID in order to check its privileges so that you can limit API access
This may be helpful: https://medium.com/#faizanv/authentication-for-your-react-and-express-application-w-json-web-tokens-923515826e0#5f52

Not sure whether you still need this - I personally feel we should have something bridging the authZ gap between server and client to make it easy. So I spent a few days on a github project for this purpose, here it is: authzyin.
What I tried to do is to leverage policy based authorization from asp.net core - which I think it's very cool - and automatically bring the same definition to the client to use in React via hooks.
For authentication I am using msal.js against AAD - so authN is done on the client and jwt bearer token auth is used for all requests.
It has a client lib and a server lib which can be used together or separately. Of course it might still be lacking some features - please feel free to take it as a reference (contribution is also welcome).

Related

OAuth2 SSO with redirect to React SPA

I have a client who is using OAuth2 for single sign on with their own login page. Once user is logged in they will be redirected back to my React SPA i'm building.
What I'm trying to find out is a way for my app to integrate with OAuth2 to keep check if user is still signed in. For example say they refresh the app I need a way to check OAuth2 if user is still authenticated.
Should I use an express server to manage the AUTHORIZATION_CODE returned by the redirect from OAuth2 ?
From what I understand OAuth2 returns a AUTHORIZATION_CODE and STATE in the redirect url.
If so how would I manage this on the express side ? Is there a express plugin to manage this process.
Or could I just bypass using express and just use the Auth0 React SDK to check if user is Authenticated ? I found this example on the auth0 docs. https://auth0.com/docs/libraries/auth0-react
Not sure if this would work because of my setup where the login happens from the client login page and redirects back to my app ?
Authorization codes are meant to be exchanged with access tokens. After you exchanged the code with an access token, what you technically need to do is to inspect the token to check whether it's active or not, with active status meaning that the user is logged in. This can be done in a couple of ways, the following are just the ones I can think of:
Most conventional way I know is to send an API request to the introspection endpoint while including the access token. The response will tell whether the token is valid and/or active.
If the token if in JWT format, it is usually possible to verify the token signature and verify the expiry time after decoding it. Depending on the authorization server, it might be possible to send this token to the introspection endpoint as well.
Unfortunately I can't help with the specifics as the OAuth2 server being used is not mentioned. But if you actually use Auth0 as your authorization server, you can probably use their libraries to help with their OAuth 2.0 flow, such as logins and auth status checks. Otherwise you might need to find another library like node-openid-client or do it manually as explained.

Login/Authentication with OAuth2 and single-spa

I've started building a prototype for a front-end layer with single-spa. The layout is very similar to https://github.com/react-microfrontends, which means:
Root config
A navbar (React)
Two apps (Both React)
A Styleguide module
An API module to handle communication with a set of API
I managed to get a basic prototype running, but I now need to implement some OAuth2/OpenID based authentication, and I'm not sure where to start. I need the user redirected to a separate URL (Auth0 style) if not authenticated or not having a valid JWT, then I need a mechanism of token refresh whenever the auth token expires. On top of any general advice on best practices, existing examples and so on, I have some specific questions I can't quite work out.
How can I redirect the user to a different URL when not authenticated? Which of the modules/components should be responsible for it?
Is there a library that implements OAuth2 out of the box? In particular, I'm interested in some sort of automatic token refresh.
What is the best way to make sure an unauthenticated/unauthorized user cannot access the app bundles?
Thanks in advance.
The typical approach would be to set up an Auth microfrontend that would :
handle credenials retrieval upon login. Be it via Password flow or OAuth ( in your case). Since you are using React, your OAuth provider should have a library that you can use within the Auth MFE to interact with it. If it's keycloak, React Keycloak is a good fit. There's no rule lf thumb here.
pass the credentials to your two React Apps ( Microfrontends) and the API module via Browser storage or shared state.
Doing so, the API module would set the credentials in the API calls. and the two react Apps would check credentials presence before proceeding with their inner logic.
refresh credentials on expiration or log out user ( depending on your logic ). Loging the user would mean deleting the credentials from browser storage for example.
redirect to one of your react App after login. That means the Auth MFE route should always be active in the root config.
I hope it helps. Here I have summarised the flow.
More of it on my github account https://github.com/exaucae/single-spa-patterns/blob/master/AUTHENTICATION.md

React multiple subdomain auth with jwt

We want develop few different services (React Apps) with the same users database and Rest API.
Some users might have access to APP 1, some for APP 2, some for both depends on their role.
We decided to go on multiple subdomain apps method.
We want SSO so only one page/app to authenticate all the apps and not a local login component for each app. using JWT mechanism in our backend.
STRUCTURE:
AUTH FLOW:
There are two main problems in this flow which are marked as 1 and 2:
Lets say i go to the login app and log in, getting accestoken from the backend.
How do i deliver the token to app1.company.com? should react login APP redirect with token in url param?
local storage is subdomain scoped.
iframe has problems with Safari.
I don't wanna save jwt in cookies for now because the flask REST can serve non-browser retailed clients.
Lets say the user want to go to app2. if we aren't able to share the token from app1 with iframes or any other method, then this app should be redirected to login and make the process again as app1, which is fine for us.
But is this really the way? if token is invalid anymore and we get Error from backend, should we redirect to the login app in the other subdomain (embed the url we wanna go back to after login success)?
Can i just use 3rd party Open id connect service?
Should i consider microfrontends approcah to make the all the "apps" on the same domain?
How "Attlassian" as an example handles this process?
What am i missing and what is the best way to solve this flow?
Lets say i go to the login app and log in, getting accestoken from the backend. How do i deliver the token to app1.company.com?
It is not a problem that login.company.com delivers the token as a parameter in the URL, because the site can verify the authenticity of the token by verifying the digital signature or with a specific endpoint in the central authentication domain. This is how openid/oauth2 does it using the "implicit" flow, although they also allows to send the token as POST, or use a 2-step flow ("authorization_code" flow)
Lets say the user want to go to app2. if we aren't able to share the token from app1 with iframes or any other method, then this app should be redirected to login and make the process again as app1, which is fine for us. But is this really the way?
You can share the token between domains using an internal iframe, but in your case I would recommend that each domain use its own token.
if token is invalid anymore and we get Error from backend, should we redirect to the login app in the other subdomain (embed the url we wanna go back to after login success)?
Yes, in the number 2) of your drawing, just redirect from app2.company.com to login.company.com and follow the same flow as in 1). You will need some type of cookie on login.company.com to avoid requesting credentials from the user again
Can i just use 3rd party Open id connect service?
Yes, you can use an external OpenIdConnect service, or deploy at login.company.com an OpenIdConnect server like IdentityServer or KeyCloak
Should i consider microfrontends approcah to make the all the "apps" on the same domain?
It is not necessary having a central authentication domain
How "Attlassian" as an example handles this process?
I don't know exactly how Attlassian does it, but currently most web services support OpenIdConnect

Getting information of user from oauth2 app having the session token

I'm having I think, a misunderstanding of concepts related with Oauth2 protocol. Right now I have 3 applications:
Frontend developed in React
OAuth2 server developed in Golang (not finished)
Another backend app, let's call it: Bussiness Logic app
At first, the user from react can login in the system using the OAuth2 server, the OAuth2 server sends the token and everything's perfect.
Now, when from the the react app some request is send to the Bussiness Logic App the token is also send in the headers. My question is: having the token, should I be able from the Bussiness Logic App to get information fo the user making a request to the OAuth server? is it allowed in the OAuth protocol?
The thing is that I need to know in the Bussiness Logic App which user is logged in, if it's not allowed, how should I fix it?
No.
OAuth 2.0 NOT an Authentication protocol.
If you need Identity Information you need to use OpenID Connect (which is built on OAuth 2.0)
With OpenID Connect you are provided both an Access Token and an Identity Token. The Identity Token will contain "basic" profile information about the "user". The Access Token may be used to obtain more detailed information about the user from the userinfo_endpoint.

AngularJS and Firebase Authentication

I would like to add an authentication mechanism to my AngularJS app with Firebase backend. The requirements are simple:
Authenticated users should be able to access any page.
If unauthenticated users goes to /some_page (any page except /login), they should be redirected to /login. Once they enter the right credentials, they should be redirected to back to /other_page.
Possible solution that is described here makes the following assumption:
My solution assumes the following server side behaviour: for every
/resources/* call, if user is not authorized, response a 401 status
But, I'm not sure if it is possible to enforce this behavior when using Firebase as a backend.
Any help and/or examples to implement such AngularJS+Firebase integration will be appreciated!
One solution is to do your routing on the client side with the $route service.
When a user authenticates through Firebase, save some record of this on the client, like in localstorage, some all-encompassing controller, or your own Angular service (my preferred option).
In your routing controller, if the user is authenticated, redirect to /some_page, otherwise redirect to /login and keep track of the $location where the user intended to go.
If, on the other hand, you want to route with your server, you could use the solution you linked to by having your server generate Firebase auth tokens.
I had the same requirement recently and came across this blog post.
http://www.42id.com/articles/firebase-authentication-and-angular-js/
It explains setting up an Angular JS application that interacts with Firebase. Also included are ways to authenticate against OAuth providers such as Google+ and Github using Firebase API, routing based on authentication status, storing user profile information on Firebase and setting up security rules on Firebase to protect user data.
If you are using Firebase Simple Login (rather than generating the authentication tokens on your own servers), you can see how to detect your login state client-side here:
Displaying text after login

Resources