How to refresh the OAUTH2 BOX token in multithreaded application - multithreading

I'm using the BOX SDK to access box.com items programatically. SDK gives me the new pair of tokens whenever current access token is expired for a single thread request.
My question is how to 'refresh' the access token in multithreaded application (website). Making the OAuthDataController.doRefresh to synchronized will solve my problem? Or do i need to put some additional logic.
P.s I've helper class to load and archive the tokens in/from txt file.
Please let me know. Thanks.

If you are writing a multi-threaded app, then you need to synchronize on the refresh block.
In java, the classic way to do this is by using a singleton. Other languages allow similar mechanisms to coordinate an operation that needs to be coordinated across multiple threads.

Related

How should I set up the auth flow when handling drive files of a user server side?

The gist of it all is that I'm trying to fetch audio metadata from a user's google drive files to store them into firebase.
At first I intended to do this locally, entirely client-sided, because my front-facing web/iOS/Android app is in flutter;
but as it turns out, there's almost no library handling audio metadata properly, and after dabbling with it, I realized I could probably get some formats (say, .wav & most RIFF-type audio files) to work, but doing an entire library to handle all kinds of audio metadata was a task significantly bigger than my original plans. Another option would be to create interfaces between C++ code and/or JS code into my Flutter application, but I'd have almost no control over that, it's not the easiest of process, and there would be possible inconsistencies between platforms.
I might make that library eventually, but in order to facilitate my work, I decided to use a server as a middleman that'd run with node and handle the file requests and metadata treatment, & also facilitate the interactions with firebase for me by making them handled by a service account.
Now, this makes me run into one issue : how to handle the google Auth.
When my user logs into my app, I get all the required auth scopes (google drive files access and write, contacts, email, etc) for my app; it goes through the consent screen and I get authenticated.
I'm still a little confused with the recommendations from google and best practices in this case, since my app, in itself, did not require an auth system outside of getting access to the google drive files through google identification, and I therefore do not have Firebase/Firestore users; I can simply store them in my (firestore) database for identification purposes (or maybe tie in the frontend flow to my firestore app to also create a user when logging in through google if that is possible. I'm currently using the google sign in
flutter package.)
To come back to my actual problem now that the situation is laid out :
Should I just transfer the auth tokens (and maybe reverify them in some ways to avoid impersonation) from my frontend app to the server through a HTTPS post request or through headers, and use them to directly query the Google Drive API (I wouldn't even need to store them outside of memory, which would be relatively safe against any attacks on the server itself), handle the files and the possibly expired token ?
Should I modify my frontend workflow so it directly grants access to my server who would handle the session rather than getting the tokens locally ?
In the first case, I would most likely simply use the users UID as identifiers for the firestore data (none of it is sensitive anyway, it would simply be playlists and some metadata). In the second case, I could probably implement a stronger security on firestore using the firestore rules,but it'd require a significant amount of refactoring and logic changes in my frontend.
In case that wasn't clear, I wish my server to make all the Drive related requests (after getting the proper authorizations from the user of course) and handle these without having to request the files locally in frontend. Both solutions (and others if available) should work, but I'm wondering what the best practice would be in the context of the Oauth2 system used by google and the fact that the authorization is transitioning between client and server and could be subject to security issues.
I'll add code/visual representations if this isn't clear enough. It is to me, but I obviously designed the mess.

Having one backend manage authentication for a webapp and react native app

Im planning on making an application that has two parts two it:
React native mobile app
Browser web-app for desktop users
I'm trying to plan out how im going to manage the backend authentication for this (Node.js, passport.js). Ideally, I can just have one backend manage it, regardless of which type of client.
Lets say im going to ONLY have google auth (for simplicity). I don't need to hit googles API's for any information (like profile, contacts, etc), I just want them to login with a google account. My understanding so far is that theres two main ways (especially since im using passport.js).
jwt based approach
session based approach
For either approach, my issue arises when it comes to the react native app. Since I'm not able to use the HttpOnly cookie, im not sure how to safely store data. e.g
In the jwt approach, if the server administers an access token and a refresh token, the react native client can just store them both in the same place e.g https://github.com/mcodex/react-native-sensitive-info. Which means the refresh token is just as susceptible as the access token, which defeats the point of a refresh token, so might as well just have the access token be long lived.
In the session based approach, react native can just store the session id some where (like react-native-sensitive-info above), and the same problem arises
My current thoughts on what should be done:
It seems like theres no way of getting around the security issue of storing information in react native, so as of now I feel like im just going to follow the JWT approach, and store the access + refresh token in react-native-sensitive-info. However, this does mean that the login endpoint is going to return the access + refresh token in the body of the request when the User-agent is mobile. When the user agent is web then we should be able to set an httponly cookie. The only thing that I can think of is if there is a malicious request that masks the user agent (is this possible?), and then can receive the access + refresh token in the body and will be able to do whatever with that.
Performance Aside
A session based storage approach seems much simpler overall. Yes it does store state on the backend, but if we did the JWT approach we would have to store peoples refresh tokens somewhere on the backend anyway (If theres ever a scenario where we need to invalidate peoples refresh tokens, e.g on logout or damage prevention).
This way, say we have a sessions table, when a user logs out, or if we want to invalidate sessions, all we have to do is delete rows from that table. In the JWT method, if we want to invalidate a refresh token, we have to have a blocklist table (which will only keep growing in size, since refresh tokens shouldn't expire, but I guess they can be dropped after a long period of time). However, if you have LOTS of users, the sessions table could get large, which could cause performance issues (but you could probably just drop sessions over a certain age)
/Aside
Questions:
Ive noticed mobile applications have NEVER asked me to relogin with OAuth. Does that mean they're constantly using their refresh token whenever the access token expires? If theres no clear way to store that in a secure way in mobile, do they just have super long lasting access tokens?
Is all of this thinking overkill? Is it fine to just store a super long-lasting access-token in react native and just use that all the time? Then when the user presses 'logout' we can drop that from local storage?
Would a third party auth system like auth0 manage all of this for me?
I'll try to share my experiencies in different kinds of app, this way things may get more clear.
Authentication Method
On most of the mobile applications (with web applications) I've worked with long term access tokens on the mobile side, most of applications don't require the user to login each time you open the app. Usually we store the token in a Secure Storage.
In some cases I've worked with a memory database (Redis) to put the user's session it's really fast and you don't need to query your main database each request (this was used for a high availability system, it may be overkill for most usecases)
Some very specific solutions may require more security, this will depend on your product (like banks, and transactions apps or apps the keep sensitive data) in these cases I would recommend you to login the user every time he closes the app or stays inactive for to long. (this kind of solution usually relies on fingerprint/faceId libs)
My personal opinion on this matter is to go with jwt, it's easy to maintain on the server side if you need to change backends and has a more defined pattern to follow, but that's my opinion and if you have high demand or some specific usecase this may change.
Storage
Talking about the storage options, there are some good suggestions on where to save data like tokens in a secure way on the react native docs,a good option I've used sometime would be:
https://github.com/emeraldsanto/react-native-encrypted-storage
but you can see more options and it advantages here:
https://reactnative.dev/docs/security#secure-storage
Third party libs
They usually helps with the basics if your projects has the budget and not a lot of customization on the authentication process, usually if it's a brand new project (on the back and front end) they work well.
Most of them will handle most of the hurdle for you like token renovation but you should mind the price scalability for these kind of approach
Wish success on your project.

Spring Security Authentication, making RestTemplate calls avoid using a String for authentication

Hi I'm having issues security my application, enabling authenticated users access to specific endpoints, non-authenticated users access to others and most importantly, continuing to enable the application to communicate with itself, without storing passwords as a String in the case base.
The code base:
My code base consists of numerous packages that communicate via REST and GraphQL calls. With no authentication, this system works fine. Development is in Java 8 with Maven.
Aim:
I am currently in the process of adding authentication to the code base which should enable three things to occur.
The different projects in the application continue to communicate easily.
An "admin" user can log in and make calls either via Swagger or GraphiQL or any methods they require.
The average user will only be able to access specific endpoints such as UI elements (e.g. localhost:8082/user-ui [unique_key])
Current Development:
I've implemented Spring Security In-Memory Authentication (https://www.appsdeveloperblog.com/spring-security-in-memory-authentication/). Which successfully blocks URLs being called and prompts the user for credentials, except on certain predefined endpoints. This fulfilling criteria 3 and part of criteria 2 (as the Admin can access Swagger and GraphiQL).
My Problem:
Unfortunately setting up this system has broken the internal calls as the RestTemplate used to communicate between packages no longer has the correct authentication.
While I could use BasicAuthenticationInterceptor(https://www.baeldung.com/how-to-use-resttemplate-with-basic-authentication-in-spring) to provide the authorization, this would mean having to write the password in a String in the code base. As I understand it, this is bad form as the String is then stored in the String pool. Elsewhere I've managed to avoid this using the CharBuffer before encoding the password, however BasicAuthenticationInterceptorrequires a String.
Any advice on how to proceed would be greatly appreciated.
If you are using basic authentication, you will have to provide the password when you are making internal calls with resttemplate. That doesn't mean you need to store the sensitive data (in this case credentials for your basic authentication) in plain text in the code base. One of the most common practices is to use an external file to store the sensitive data and then get the application to use them at run time. You may also want to ignore that file from git repository to prevent that being part of the code base.
If you are using Spring boot have a look at the environment specific properties files, which could be an ideal way to store profile specific configuration and data like these.
https://docs.spring.io/spring-boot/docs/1.5.5.RELEASE/reference/html/boot-features-external-config.html
https://www.baeldung.com/properties-with-spring
If you are worried about storing the credentials in plain text in properties file, you can also encrypt sensitive data in your properties files.
Spring Boot how to hide passwords in properties file

Rest API real time Tricky Question- Need Answer

I was recently interviewed by a MNC technical panel and they asked me different questions related to RestAPI , i was able to answer all but below 2 questions though i answered but not sure if those are correct answers. Can somebody answer my queries with real time examples
1) How can i secure my Rest API when somebody send request from Postman.The user provides all the correct information in the header like session id, Token etc.
My answer was: The users token sent in the header of the request should be associated with the successfully authenticated user info then only the user will be granted access if the Request either comes from Postman or application calls these API.(The panel said no to my answer)
2) How can i handle concurrency in Rest API Means if multiple users are trying to access the API at the same given time (For e.g multiple post request are coming to update data in a table) how will you make sure one request is served at one time and accordingly the values are updated as requested by different user request.
2) My answer was: In Entitiy framework we have a class called DbUpdateConcurrencyException, This class takes of handling concurrency and serves one request is served at a time.
I am not sure about my both the above answers and i did not find any specific answer on Googling also.
Your expert help is appreciated.
Thanks
1) It is not possible, requests from Postman or any other client or proxy (Burp, ZAP, etc) are indistinguishable from browser requests, if the user has appropriate credentials (like for example can observe and copy normal requests). It is not possible to authenticate the client application, only the client user.
2) It would be really bad if a web application could only serve one client at a time. Think of large traffic like Facebook. :) In many (maybe most?) stacks, each request gets its own thread (or similar) to run, and that finishes when the request-response ends. These threads are not supposed to directly communicate with each other while running. Data consistency is a requirement of the persistence technology, ie. if you are using a database for example, it must guarantee that database queries are run one after the other. Note that if an application runs multiple queries, database transactions or locks need to be used on the database level to maintain consistency. But this is not at all about client requests, it's about how you use your persistence technology to achieve consistent data. With traditional RDBMS it's mostly easy, with other persistence technologies (like for example using plaintext files for storage) it's much harder, because file operations typically don't support a facility similar to transactions (but they do support locks, which you have to manage manually).

How to customize the behaviour of SecurityContextPersistenceFilter?

I developing a stateless REST API that makes use of token based authentication, where I'm manually adding an Authentication object to the security context by calling SecurityContextHolder.getContext().setAuthentication(authentication) from within a custom security filter. I've been experiencing problems with the context not being set correctly which I believe is due to this :
Storing the SecurityContext between requests
In an application which receives concurrent requests in a single session, the same SecurityContext instance will be shared between threads. Even though a ThreadLocal is being used, it is the same instance that is retrieved from the HttpSession for each thread. This has implications if you wish to temporarily change the context under which a thread is running. If you just use SecurityContextHolder.getContext(), and call setAuthentication(anAuthentication) on the returned context object, then the Authentication object will change in all concurrent threads which share the same SecurityContext instance. ...
You can customize the behaviour of SecurityContextPersistenceFilter to create a completely new SecurityContext for each request, preventing changes in one thread from affecting another.
So the question is - how do you change the behaviour of the SecurityContextPersistenceFilter?
I'd like the security context to not be associated with the http session, but don't want to set the session creation policy to stateless, because I still want to implement CSRF protection etc.
I had this exact question this afternoon, and this open question matched my search exactly, so I thought I would add the little I learned.
We had threads that were accessing the same SecurityContext. I was unable to figure out how to customize the behavior of the SecurityContextPersistenceFilter directly (and in the pattern of the framework), however there were two ways that I could get it to be thread safe.
The first solution was to ensure that an empty context was created in our main authentication filter. This covered all of our authenticated requests, so it would work for our solution.
SecurityContextHolder.createEmptyContext();
The second thing that worked for me was to change our WebSecurityConfig to be stateless, which I know doesn't work for the OP, but added here for completeness.
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
...
Both these solutions work independently for our particular configuration. I'm certain there is a 3rd solution that would read better, but I don't know what it is but would like to.
This is my first time posting. I welcome any feedback.

Resources