I’m exploring an opportunity to expand the security requirements for an OWA through JWT Tokens and React Middleware. As I discussed with @mogoodrich already, I’m moving this thread here to get your ideas on the following idea
Still, we don’t have any tokens for authorizations, only depends on the server session based login system. Since we are moving towards the React based UI modules, I feel good to move for token management such as JWT. I have explored about JWT in OpenMRS, and I could find a ticket (RESTWS-648) regarding this but I can’t find any implementations.
In the React-Components also, we depend on the session for login and authorization. See here . So it should need an HTTP Request to handle each and every user authentications before providing services, it might cause unwanted delays for users.
Suggestions -
I would like to move this implementation to Core-Authorization filter rather than having it in RESTWS module. So each authentication will have a unique JWT token based on the configurations.
Attach some non-sensitive user data, and user Access Scopes along with this token
Implement a unique REST Endpoint for user authentications and issuing tokens (Not with session endpoint) - eg: openmrs/rest/v1/auth
Implement a react logic to fetch JWT tokens of the authenticated user from server and store as a cookie/session/local storage in the browser.
Still I can’t see any middleware components in React-Components rather than sagaMiddleWare. So I wish to have a middleware which checks for user access/authentications through the JWT token stored in the cookie/session/local storage in the browser without having an HTTP request to the server.
After this idea, A React-OWA will not reach the server for validating user access/user authentications before providing services. If the user JWT token is expired, the React-OWA will launch thelogin screen for relogin.
I’m expecting your suggestions to move this idea for GSoC 2019
I asked in order to understand what you did mean by “So it should need an HTTP Request to handle each and every user authentications before providing services, it might cause unwanted delays for users.”
Actually it should be updated with clear information as below,
We need to attach user name and password via the REST authorization headers while accessing the restricted endpoints. In such a case, We need to popup and ask user to enter username and password each and every time (AFAIK storing username and password in client side browser is not a good practice).
We can easily use JWT tokens in these cases to avoid multiple login requests and unwanted user interruptions.
@dkayiwa for what it’s worth, in the openmrs-react-components module we use this method for authorizatoin (the third bullet point, not the atlernate session token method) so this is likely what @suthagar23 is referring to:
* Currently, only BASIC authentication is supported. Along with the HTTP request, a request header of **Authorization: Basic (base64 of username:password)** needs to be sent.
* Alternatively, a session token can be used. **GET /openmrs/ws/rest/v1/session** with the BASIC credentials will return the current token value. This token should be passed with all subsequent calls as a cookie named jsessionid= *token* .
However, I too would like to learn the value of using JWT vs a JSESSION token vs passing the base64 of username and password evert time… from a performance perspective, I haven’t noticed any issues with the base64 method but my knowledge of the pros/cons of different authentication issues is limited…
@suthagar23 i have not yet seen a practical advantage that JWT would give us over our already available authentication options. Is there something that am not seeing?
I guess if OpenMRS implements JWT then it can easily used as an authentication server (identity provider) by other services. Suppose I want to build a simple system that sends SMSes and I want this system to be independent of OpenMRS, but, at the same time I would like the health care providers in my OpeMRS server to be the ones to set whatever parameters to be used with my SMS system. Instead of re-implementing an authentication service, I can use OpenMRS instead.
@dkayiwa, AFAIK most of the modern web applications are moving towards the JWT token based authentications instead of Session Tokens. Because,
All client-side information will be stored in the server side for a session based authentications, and it will decrease the performance when a huge number of users are accessing the system concurrently. But for JWT, all the client information will be embedded into a token and kept in the client side (Cookie, session, or local storage). So the client side will perform actions independently from the server side.
Scalability of the OpenMRS will be an issue when we totally adapt to a session based authentication system(It will be stored in a server). There is no issue with scaling because JWT token is stored on the client side.
Cookies or Sessions in server normally work on a single domain or subdomains and they are normally disabled by browse if they work cross-domain (3rd party cookies). So It may cause issues when APIs are served from a different domain to mobile and web devices. But there is no issue with JWT, since it simply included in the request header. So it can work across any cross-domain servers.
Further, as @willa said above, It will be a barrier when we integrate OpenMRS services with other platforms through session based authentication (in server side). JWT based authentications may reduce the barriers on this level of integrations since it’s doesn’t have any dependent information on the server rather than some secret configurations. (Need more analysis on these integrations)
One other benefit of using JWT tokens is that it is reasonably easy to implement using libraries available in probably every language you can expect to have it
Another benefit: Because the JWT can carry “information” and this can be accessed by the client you can now start do some smart things. For example remind the user that their session will be expiring a few days before they are logged out, giving them the option to re-authenticate, based on the expiry date in the token ,since they have built-in expiration functionality ,etc which Session Ids do not have
To make sure that am not misunderstood, am not against JWT. Am just cautious and slow at jumping to some of these new technologies unless am sure that they are solving a real practical (non theoretical) problem that i have. Some body else’s problem may not be a problem for our project. Therefore, it is with this background, that am engaging you on this front. That way, we get a fair balance of the pros and cons. Creating more code to maintain, needs to pay us back by solving our real problems. I have also seen anticipated problems that never become a reality with particular projects.
Am curious to know some of those modern known web applications that have moved towards JWT. Can you list any examples? I usually want to learn from the experiences and mistakes of the early adopters.
I am with you on this, other than using OpenMRS as an independent identity provider I think we don’t really need to have this feature, at least not now. Besides some of the things about session ID applies to JWT too, for example, you will have to store them somewhere on the browser and it is not uncommon to store them as cookies too. As for the cross origin requests one can setup the correct headers (I believe it is not too much of a hustle).
I agree with you @dkayiwa, JWT has some drawbacks compared to JSessionIds in terms of security . Anyhow, I had to implement it while working on a Cloud Solutions which wanted to handshake with other API Providers and Auth Clients as @willa mentioned. That’s the idea behind me while thinking of this idea .
So then, What do you think about having this feature as a separate module which can help others to integrate other services and clients which depends on JWT?
@suthagar23 i first of all would like to appreciate your unending innovations and looking out for ways to make OpenMRS better. Please keep that up!
Do you know of any existing OpenMRS client or implementation which has that problem and hence in need of such a solution? The only reason am asking is simply for taking into consideration the limited resources and how we split them between real already existing implementation problems vs those that we just anticipate, which may not become a reality. At least not in the near by future.