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.
Related
I need to implement a system where the frontend is a pure SPA made with react (by pure I mean it is only hosted as a bunch of static files) and a nodejs REST API made with express. I can not use any 3rd party authentication providers like Auth0, etc. so everything must work locally.
The app must have authentication and it must be more or less up to modern standards. I am looking to implement PKCE flow with short-lived JWT auth tokens and long-lived refresh tokens.
There is one thing I am confused about. Every guide on PKCE flow always mentions redirects from one URL to another during the auth flow. In my setup, however, redirects are highly unwelcome.
I want to check and find out whether it is OK to implement PKCE flow using pure XHR requests to communicate between the SPA and API. Is it appropriate to do so? What major risks are there compared to a setup with redirects?
EDIT: to make this question more specific, what should be the PKCE authentication flow if you can only use SPA and XHR (and must avoid redirects)?
There is one thing I am confused about. Every guide on PKCE flow always mentions redirects from one URL to another during the auth flow. In my setup, however, redirects are highly unwelcome.
The whole point with OAuth 2.0 is the delegation (redirect) to the ID Provider, such that the user always send his password to the ID Provider instead of sending the password to each application. So you will always need to redirect the user to sign in - but hopefully the user is already signed in, so he immediately becomes redirected back to your app. There are techniques to check if the user is signed-in using XHR, that can be used until he need to sign in.
what should be the PKCE authentication flow if you can only use SPA and XHR (and must avoid redirects)?
In the Authorization Code flow, the client typically does two request to the ID provider. The request to authorization endpoint typically is done through a redirect (e.g. in case the user need to authenticate), but the second request, to token endpoint can typically be done in the background using XHR or fetch using appropriate CORS configurations.
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).
Does the msal library prevent token replay attacks?
How does it stop someone from taking the access token from the redirect URL and using it in another application?
I'm not sure if Azure AD handles the protection or Microsoft Authentication Library (MSAL) Microsoft
How does it stop someone from taking the access token from the redirect URL and using it in another application?
MSAL can't really do anything about something accessing the URL.
That's the browser's duty.
Same-origin policy requires that only script on a page with the same origin can access the URL of an iframe.
So even if I put an iframe on my website that did hidden login for one of your apps, I wouldn't be able to get the token if the redirect URL is on a different hostname from mine.
So let's say your app has one reply URL configured: https://yoursite.com/aad-callback.
If I wanted to take the token, my site would need to be hosted on yoursite.com.
There is no way for me to ask AAD to return the token to another URL.
Another choice would be to intercept it in flight to your app.
But that would require man-in-the-middling the TLS connection.
If someone can do that, you have bigger problems.
Replay attacks are prevented by using nonces, a new value is set in each authentication request: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/3fb9ce5a16ea462336eee62b496dfae8611f0fbc/lib/msal-core/src/AuthenticationRequestParameters.ts#L39
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.
I'm building a SPA with AngularJS with communication to a Laravel PHP backend. The Authentication method uses JWT, with the tymon/jwt-auth PHP library, which seems to me like a great library.
When user sends his username/password, the service sends back the JWT, which is stored in localStorage on the client. This works fine. However, I want to use a refresh token to continue issuing fresh JWTs to the client, to keep the user logged in as long as he is using the application. Where are these refresh tokens supposed to be issued? Should they be issued when a user sends his username/password? If so, there doesn't seem to be a way in the tymon/jwt-auth library to send the refresh token to the client. Please help, I'm having a lot of trouble conceptualizing how this is supposed to work.
Whether or not you get issued a refresh token when you authenticate with an OAuth 2.0 authorization server depends on which OAuth grant you're using.
When your client is a SPA (an untrusted client), you're probably using the implicit grant and that grant does not support refresh tokens.
Some companies have implemented libraries that are able to refresh access tokens issued by the authorization server using requests in a hidden IFRAME. I'm not familiar with the library you are using.
See also this question for more info.