Where are refresh tokens generated in a JWT Authentication scheme? - angularjs

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.

Related

How can I get access- and refresh-token from Azure AD B2C using a certificate?

Context
We are transitioning our Spring Boot application (with Angular frontend) from Spring's build in OAuth2 based security to Azure-AD. This is working well for clients we can update right away (mainly the B2B clients). However some (most B2C) clients can not easily be updated at the moment. In time this will happen, just not now. So I need a solution for the mean time.
Our idea
We proxy the request for the Azure tokens via the Spring Boot backend. From the client's point of view, it would look like the old solution. Username and password would be authenticated against the backend's database. Upon successful authentication, a certificate would be looked up for the user and this would be used to aquire an access and refresh token from Azure-AD B2C containg also a token for B2B.
That token would be wrapped into Spring's old OAuth2AccessToken and sent back to the client. The refresh request would be proxied in a similar way.
I have the refresh part working based on this: Web sign in with OpenID Connect in Azure Active Directory B2C -> Refresh Token
The problem
Using Microsoft's Graph API I can get an access token, but the part of the MsalToken extends AccessToken that is public (AuthenticationResult implements IAuthenticationResult) does not let me access the refresh token even if I request scope offline_access and if it is contained in the result.
Questions
Are there security concerns that make this idea a fundamentally bad idea? I'm aware that this requires trusting the backend, but that was the case so far. To me that does not seem to make it worse.
Is there a way to get an access- and refresh-token for a user be presenting the users certificate (or another none-interactive method - but we do want to use MFA as well for updated clients). I tried using Microsoft's Graph API, but a direct web-request is fine too.

Microsoft Graph - OAuth2.0 flow for React client and spring-boot backend

I am building a React-based SPA that communicates with a spring-boot backend via a REST API. I need the user to be able to log into their Microsoft account on the browser client (the SPA) and I need the backend service (spring-boot app) to be able to query Microsoft's Graph API on behalf of that user.
After reading up on the Oauth2 flows, the authorization code flow (not the PKCE flow, just the regular authorization code flow) seems the most appropriate. The browser client could let the user log into their Microsoft account, retrieve an authorization code, and send the authorization code to our backend service via HTTP request. The backend service (which is trusted and can safely store a client secret) can then request an access token, make requests to the Graph API directly (meaning that the SPA would never need to make any requests to the Graph API), and silently refresh the token as needed.
However, I cannot see any examples of anyone using this flow to access Microsoft's Graph API.
Looking at Microsoft's documentation, it seems like they recommend using the on-behalf-of flow. But this flow requires the browser client to request an access token and then use that to communicate with the backend service (which in turn can communicate with the Graph API). It doesn't make sense to me why the access token cannot be requested on the backend using a client secret. Wouldn't this be a more secure and preferred method than having the client retrieve the access token, as is done in the on-behalf-of flow?
The Oauth2.0 site, recommends that SPAs should either use the authorization code with PKE or the implicit flow, but I do not see an option to use the standard authentication code flow for SPAs. Should I take this as an indication that SPAs should not be using the standard authorization code flow as I described earlier?
Despite not finding a clear-cut example of the standard authorization code flow in Microsoft's documentation for a react frontend + java backend, I tried to go about doing this myself. However, using the #microsoft/mgt-react and #microsoft/mgt-element libraries to do this are not straight forward. For example, the #microsoft/mgt-element notion of a Provider supports a call to retrieve an access token, but doesn't clearly expose the authorization code. If I wanted to do the authorization code flow described earlier, it seems like I would need to use raw HTTP requests, which I know is not a recommended way of accomplishing this.
Summarizing my questions:
What OAuth2.0 flow should I be using: 1) authorization code (access token is retrieved by backend service using client secret), 2)
authorization code with PKE (access token is retrieved by client), or
3) on-behalf-of flow (access token is retrieved by client, seems to be an extension of PKE flow)?
If using the on-behalf-of flow, does the SPA just include the access token in the header (marked as 'bearer') and the backend service just
includes that same header to query the Graph API, or does the backend
service need to request another token before querying the Graph API?
Agree with #ch4mp to call graph api directly in SPA if it's allowed. If not, then I recommend you using on-behalf-flow or client credential flow based on your requirement.
Let's come back to your requirement -- call ms graph api in a springboot api project. First, let's see one of the graph api getting user api. You can see permission types here: Delegated which means call graph api on behalf of the user, Application which means calling api on behalf of the application(your spingboot api project) itself. If you want to call api behalf of the user, then you have to use on-behalf-of flow. This is because the api project which will be considered as a daemon application, so the project itself doesn't have a UI page to let users enter username/password to sign in and get authenticated.
You can certainly use ROPC flow which have to pass the username/password to api but I really think it unsafe, so I don't recommend.
If it's not necessary for you to call graph api on behalf of user, you can certainly take client credential flow into consideration. But pls note here, application type api permission is a "large" api permission which always have name like User.ReadWrite.All, Mail.ReadWrite.All and it always means the application can not only query user information but also be able to modify user information.
If you want to use on-behalf-flow, then you may review this answer and it explained the whole progress...
I would use authorization-code flow (with PKCE) to get an access-token and then refresh-token flow to "maintain" this token, both from client.
Authorizing the request to your resource-server with this token only makes sense if Microsoft authorization-server is your main authorization-server. Otherwise (user also logged in with an authorization-server of your own or not using OAuth2 betwean React and backend), you can still send Microsoft access-token in request body.
In any case, when issuing requests in the name of the user from the backend, do as you suggest: just set the access-token sent by the client as Bearer Authorization header (token is retrieved either from Spring security context or request body). Backend fetches a new access-token (using client-credentials flow) when issuing requests in its own name (without the context of a user).
Side note: have you considered calling Microsoft API directly from React client? If you don't have to store the result of that call on your resource-server (i.e. call graph API to display data and store only what user selected from that data), that would save quite some latency on the client and costs (network and CPU) on the backend.

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.

Is this user authentication process reasonable?

I've been developing RESTful API server communicating with cross-platform clients such as Android, iOS, Web browser, and so on.
When a user login successfully by username and password, this server issue an access token(JWT, 5 minutes) and a refresh token(GUID, 20 days).
When we develop Android client app communicating with server, we just can store this tokens in mobile device and I believe it will not be a problem in terms of security( using SharedPreferences).
But when it comes to Web browsers, (React App) I had to tackle where to store these tokens. Finally, I decided HttpOnly Cookie, because I can manage easily CSRF attacks rather than XSS.
Soon, I doubt this is a typical design. For example, web browser users cannot logout whenever they want. So I determinate change the wrapper server(Node.js) between the React app and the RESTful API server.
In my second design, the React App and the wrapper server authenticate session-cookie model, using passport.js for exmaple. And when the wrapper recognize the request is authenticated, then the wrapper issue a short term access token(1 minute JWT) and reorganize the request by inserting the access token just issued in the header sent to the RESTful API server.
Is this reasonable process? Thank you in advance.
You could simplify your solution by removing the JWT access token altogether. The refresh token could be used as a session id. Every time a client issues an API call to the server the session id is sent in an HTTP header, so you can check if the request is legitimate.
Your approach of using a JWT token with a short expiration time is ok, but it brings some complexity to your system. In my opinion this approach is best suited for systems where you have an authentication service and a resource owner service. So the client would request an access token to the authentication service and use that token to communicate with the resource owner service. Then the resource owner can check the validity of the access token by just checking whether the signature matches the authentication service's.
I hope this helps you, let me know if I'm missing something.

OAuth implict grant flow and refresh token

For now I have Asp.Net WebAPI and client application (Angular) on separate hosts. As for authentication, WebAPI uses default external OAuth provider (Google) implementation with middlewares, external bearer token and cookie. Since web application is being hosted separately, for security reasons it is using Implicit grant flow, so access_token is being returned after hash symbol in URI. Also, it means that refresh token can not be implemented.
Here comes the part I am a bit confused about.
As for my WebAPI I am using Local accounts, which have to be created for every new user that comes to my application externaly (from Google) using basic information it provides. So the external bearer token and cookie are only used till I register the user, sign him in and provide LOCAL AUTHORITY bearer token which can be used to access secured API endpoints. It means I still have the LOCAL AUTHORITY provider which lives in my WebAPI and manages access_tokens.
Does it mean that I can implement refresh token?
If I understand correctly refresh token is not valid between Google and my app (because it is using implicit grant flow), but it is viable between my WebAPI and Client application without leaving security holes?
I am a bit confused about the refresh token here. Is it possible?
Thanks for your time.
Kind of Solution
Read this answer for the solution

Resources