Why is Spring boot User Session stored in ThreadLocal a bad pratice? - spring

I'm new to an ongoing project/company and this project is using ThreadLocal to store user session data. It's a Springboot project.
I already know that this is BAD design, but i'm trying to find documentation to explain then why this will probably fail badly when the number of users/requests grow.
Can someone help me with links that explain the relation of Threads and Spring Sessions or provide an explanation on how this is a design flaw?

Related

What is the best way to make Jhipster auto generated application have SAAS model?

Like Jhipster generated app has out of box user management, I want to create a company/organization concept in JHipster so that every data is associated with its own organization/company
What is the best approach to handle it?
Have someone done it before?
First, for the database you should look at multitenancy in Hibernate and precisely at the discriminator column approach described in
https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#multitenacy and https://www.baeldung.com/hibernate-5-multitenancy
Then, for the REST layer, you should consider implementing a Spring MVC interceptor to map authenticated user to tenant id. For debugging purpose, you should also consider setting the tenant id in logback MDC so that you can see it in logs.
Finally, you got to think at the admin part, administrators should probably be able to access all data from all tenants. If admins should not be allowed to do so, you should consider encrypting data with a key per tenant.
There's a blueprint but it's not working for current JHipster 7 and team is looking for contributors. However, there are examples generated that you could look at for inspiration, https://sonalake.com/latest/multi-tenant-applications-with-jhipster/

Want ressource to implement Authentification with Spring Security in Spring WebFlux

everyone. Please i'm new in spring boot. Someone has ressources or project to implement spring security authentification (Login, Logout, Autorisation)
Please
Well you have to search this on your own. But as a starting point read this https://spring.io/guides/tutorials/spring-security-and-angular-js/.
Read it, play with it.
Probably you may need to read it multiple times if you are new to security stuff (I had to read it many times).
If you are really really new, start from the basics (ex: authentication vs authorization).
The journey is hard, but worth it (go for youtube resources as well, probably will make a difference in speed of the journey).
After all this is security we are talking about, right? :)
Good luck.

Spring session for session sharing(clustering) between servers

I'm trying to let two machines with the same base domain (subdomains differ) to share session.
spring-session-jdbc seems to be a solution I could use to achieve the goal.
When a user logs into server-a, session info is stored in SPRING_SESSION db.
What worries me is the fact that custom org.springframework.security.core.userdetails.UserDetails class is stored in that db as well.
When server-b tries to read session data from the db, it has to use the same custom subclass of the org.springframework.security.core.userdetails.UserDetails.
So I'm copying codes that relates to the UserDetails class from server-a to server-b.
I'm feeling a little awkward doing this, because server-a and server-b might want different UserDetails in general.
Is this really intended way of using spring-session-jdbc ?
Another question is, is it mandatory to use spring-security for both server-a and server-b?
Spring Session is meant to easily enable session clustering, i.e. have the multiple instances of the same app share the external session store therefore making it easier to scale your app.
For the problem you are trying to solve it might be a good idea to use an appropriate higher level protocol such as OAuth 2.0 and OpenID Connect and implement single sign-on without coupling you applications through the session store.
While the idea of sharing session store between different apps might seem convenient initially, such arrangement is usually very problematic, as you noted yourself with the UserDetails example.
In line with Vedran Pavic's answer it sounds like you should be using sso. That said there are instances where different code bases may want to share the same session such as in micro-service clusters. In this case you should simply put your UserDetails into a base jar/module that the other jar/module's are dependent upon. You can use a build automation tool to make this packaging easier to accomplish.
To answer your final question, if these two applications are regularly communicating with each other then I'd recommend either using spring security everywhere or nowhere.
Default mechanism to persist and load session is through the SecurityContextRepository (Spring Security) or SessionRepository (Spring Session).
If you use Redis for session sharing the repository implementation could be RedisSecurityContextRepository (spring-security-redis) or RedisIndexedSessionRepository (Spring Session).
The latter one for sure serialize UserDetails so you cannot share the session unless you use same Frameworks & user classes versions.
I would use custom SessionRepository and store shared user info in portable Json or XML, or whatever you like, not the Java object serialized ))

Spring Api and Mongo DB

we currently have a REST Api and it is connecting to Oracle, through Hibernate.
We are contemplating the idea of experimenting using MongoDB as a the database, and I was wondering if people could share their experience.
Obviously it won't be a simple switch. The way we persist and retrieve needs to change. Hibernate might no longer be required.
Is the best practice to design such that the Documents are stored as the Api response should be; it no transformation required?
Thanks for sharing your experience.
Cheers
Kris

Uniqueness of Session ID in a Distributed environment?

We are using Spring Session (backed up with pivotal Gemfire) for our Spring Boot applications running in an Distributed environment.
In such a distributed environment,
does Spring Session ensure that a unique session id is used for new
sessions being created across different JVMs ?
Just reviewing old SO posts for Spring Session Pivotal GemFire support, so my apologies your question never got answered in a timely manner.
In a nutshell, Spring Session uses the UUID class to generate "unique" Session IDs. For instance, see here, or more generally, here.
NOTE: Spring Session Data Redis support uses/wraps the MapSession class to store Session state in Redis, by default.
There are appears to be a lot of discussion about the effectiveness, or rather uniqueness, of UUID across JVMs in a cluster. This one in particular, though dated, caught my attention as it originated from the Oracle Java community forums.
However, keep in mind that it is your application(s) use of Spring Session that ultimately determines whether Session IDs are unique; i.e. it is not dependent on the number of nodes in a GemFire cluster since individual GemFire nodes are not generating the Session ID (applications using Spring Session are).
Therefore, if only 1 application (probably not likely in the Microservices state of the world) is ever present with Spring Session in use, then the UUIDs are probabilistically guaranteed to be unique. Even then, based on references available, it seems highly unlikely that 2 or more "application" nodes employing Spring Session will ever generate IDs that collide (though, (almost?) anything is possible ;-).
Though, I suppose if it is of paramount concern/importance, following with the beautiful tradition of Spring, it would be a simple matter to extend the GemFireOperationsSessionRepository and override the createSession() method, calling the appropriate GemFireSession constructor to pass the desired Session ID in.
However, in all cases (GemFire, Redis, etc), the Session ID uniqueness problem is agnostic of underlying, backing data store.
Hope this helps...
Cheers!

Resources