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

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/

Related

Spring Boot: Handle configuration in multitenant application

I am implementing a Spring Boot application which will be providing a multitenant environment. That is achieved in my case by using a database schema for each customer. Example see this project.
Now I am wondering how to implement tenant-specific configurations. I am using #ConfigurationProperties to bundle my property values, but these are getting instantiated once and not for each tenant.
What if I would like to use Spring Cloud Config with multiple tenant specific git repository as an configuration backend. Would it be possible when using a jdbc backend for Spring Cloud Config?
Is there any way with default Spring mechanisms or do I have to implement a database based configuration framework myself?
Edit: For example I have two tenants called Tenant1 and Tenant2. Both are running over the same application in the same context and are writing in the database schemes tenant_1 and tenant_2.
Identification of tenants is happening over keycloak (see Spring Keycloak multi tenant example). So I identify the tenantId from the jwt token and select the database connection like described here.
But now I would need the same mechanism for #Configuration beans. Since #Configuration beans are as far as I know Singletons, so there is always ONE configuration per application scope, and not ONE configuration per tenant.
So using Spring Cloud Config Tenant1 is using https://git-url/tenant1, Tenant2 is using Hashicorp Vault as backend and perhaps Tenant3 will be using a jdbc based configuration backend. And all of that in ONE (of course scalable) application.
In case your application uses tenant specific files (html templates etc), the following can be applied. As I have used the below approach for handling many tenants and works fine and easy to maintain.
I would suggest that you maintain a consistent configuration source (JDBC) for all of your tenant configurations. This helps you have a single source that is cacheable and scalable for your application. Also, you could have your tenants navigate to a configuration page to manage their settings and alter them to suit their needs at any point of time on the fly. (Example Settings: Records Per Page, Theme, Logo, Filters etc...)
Having the tenant configuration in files in git will be a difficult task when you wanted to auto-provision tenant's when they sign-up as it will involve couple of distributed services. Having them in a TenantSettings table with the tenantId as a column could help you get the data in no time and will be easy.
You can use Spring Cloud Config for your scenario and it is adoptable. It is easily configurable and provides out of the box features. For your specific scenario, you can have any number of microservices running yet all controlled by one Spring Cloud Config Server which is connected to one Git Repository. Your all microservices are asking configuration properties from Spring Cloud Config Server and it is directly fetching properties from Git Repository. That repository can have multiple property files. It can hold common properties for all the microservices or specific service based configuration properties. If you want to keep confidential properties more securely, that is also made possible via HashiCorp vault. I will leave an image below for you to get a better idea about this concept.
In the below image, you can see the Git Repository with common configuration property files and specific configuration property files for different services yet in same repository.
I will add another image for you to get a better idea how does this can be arranged with application profiles as well.
Finally I will add something additional to show the power of Spring Cloud Config and out of the box features it allows us to play with. You can automatically refresh configuration properties in running application as well. You can configure Spring Cloud Config to do that. I will add an architectural diagram to achieve that.
References for this answer is taken from Spring in Action, Fifth Edition
Craig Walls

Using Spring ACL in a complicated access setup for an entity

I am developing a spring boot application with spring-data-rest being one of the core dependencies. As such, in order to secure the auto generated and manual endpoints I have been using a role based approach and a custom PermissionEvaluator to handle object specific auth checks. This works but is too cumbersome and fails when I need a filtered and paginated response. So, I am planning to implement ACL. Now, I have a rather complicated flow of authorisation for an entity.
The users are mapped to a profile entity(MANY TO MANY). The target entity is also mapped to a separate profile entity(MANY TO MANY) and these 2 profile entities are mapped to each other(MANY TO MANY). To check if a particular user has permission over a target entity object, I need to go through the relationships in my application logic, in my PermissionEvaluator.
Now, if I decide to implement this in ACL only, I am confused as to how to best to do this. The preliminary idea that I had is to create the object list directly in the ACL tables for each user(principle). This would mean that I would need to update the ACL tables everytime with new objects if a permission is changed. Is this a correct approach? Is there a better way to do this? Is it even ok to modify the ACL tables frequently?
Summary: If the logic to check if a user has access over an object is complicated and requires data from other tables, how do I handle it efficiently using ACL?
I'm working on an ACL extension for Spring Data JPA/Rest which handles all of your problems - and many more. It take some time to learn how does it work, but it still needs much less time than creating all of these features for yourself.
You can set up the access rules using annotations in the entity classes - and that's all. it will affect the auto-generated and manual endpoints and even the Data JPA repository-methods.
Spring Data JPA ACL

Spring Security Domain Model Authorization

Spring Security has this basic idea of a Principal and GrantedAuthority. I've implemented Spring Security and read this stackoverflow and understand at a basic level that a "ROLE" is nothing more than a GrantedAuthority prefixed with "ROLE_".
What I don't understand is why have this convention in the first place? Why have #PreAuthorize("hasRole('XYZ')") be equivilant to #PreAuthorize("hasAuthority('ROLE_XYZ')")?
What's so special about segregating Granted Authorities like this? What's the purpose?
Additionally, what is the best convention for applying these "ROLES" to specific instances of a Domain Model. Take for example a system that keeps track of projects and you want to explicitly give users access to view and edit certain projects. I could create ROLE_EDIT_PROJECT and ROLE_VIEW_PROJECT but that's application-wide. Where would you make the relationship of a ROLE to a specific project? A join table? Would you even involve Spring Security into this or build this type of security from scratch within your application?
I unfortunately don't know why this convention is used, probably just legacy code I would guess.
For the second part of your question, I would suggest using "hasPermission(project, 'view')" and define your own PermissionEvaluator.
more information can be found here

The best web login approach

I am developing a jsp dynamic web project on eclipse.
I want to create an website with login functionality. I intend to store users' accounts and passwords in MySQL database. Of course, different users have different roles and rights to access different web pages. What is the best approach to implement it?
So far, I know these approaches:
1) Users enter accounts/passwords in login.jsp. LoginServlet then connects to MySQL database to check if it is correct. AuthenticationFilters will make sure only users with rights can access certain pages.
2) Use Role Based Authentication by declaring user roles in web.xml. I find this approach is not flexible, because I need to declare roles in advance.
3) Use HttpServletRequest's login/logout methods. I have not studied it.
Is my understanding correct? Could someone gives me some suggestions? Some clues would be very helpful!
Besides, I know that using POST alone to send passwords is not safe enough. Many websites suggest to use HTTPS connections. So if using HTTPS connections, does it affect the approach I choose to implement the login function?
Thanks!
--
Now, I know I need to use Spring. But Spring seems difficult for me... In Spring website I cant find out the link to download jar files. The user guide says I need to use Gradle or Maven, which I haven't used before, and have no idea why I need them. Besides, there are many Spring projects. Which one should I choose? Spring framework?
--
Have you looked into using Spring Security? It's built for just that. You don't need to be familiar with Spring but it may help.
Here are a couple of tutorials that use database authentication:
1: Spring Security Authentication and Authorization Example with Database Credentials
2: Spring Security Login Example with Database
Edit:
You don't have to Maven or Gradle. You can simply add the jars to your build path and they will work. The only projects you need to implement for the login to work is the Spring Framework and Spring Security.
To use Spring Security without Maven or Gradle:
Download the Spring Framework jars, unzip them, and add them to your project and build path. It's probably a good idea to find a hello world tutorial using Spring to get you started. A quick Google search should turn up many results.
After you have Spring implemented in your project, download the Spring Security jars, unzip those, and add them to your build path. The links to the tutorials that I previously posted will get you started. They may take a little while to go through and you may not understand exactly what is happening behind the scenes, but once you get it set up is works outstanding. I'm also not sure if you are using xml configuration or Java config but I believe those tutorials are for xml.
Spring Security was built so that it could be added to any project and have you up and running with basic configuration in about 15 minutes. After you get the basic login going (it will use the generic login form), you can search for how to implement your own custom login form, add permissions or restrictions to users and url patters, adding custom filters, etc. I encourage you to spend some time learning it as it is highly flexible and customizable.

Is there a way to bypass all security checks in Spring Security?

I'm coming from the PHP world. The framework I used most is Symfony which is heavily based on ideas from Spring. One if its bundles called JMSSecurityExtraBundle supports a role ROLE_IDDQD that you can activate via configuration. Authenticating with that role would effectively bypass all the security checks — be those Web security constraints or constraints directly on methods of classes in the domain layer.
Since security related tests needed a user with a particular role to be authenticated, I would authenticate a user programmatically creating an authentication object and passing it to the security context. That way I could test security constraints directly on the domain code without involing any UI.
Since a lot of domain methods would be secured, it would prevent me from setting up fixtures for some of the tests because the currently authenticated user wouldn't have enough permissions to do that. This is where I started using ROLE_IDDQD — I created a method that would take a function that could do anything in the domain layer bypassing any security constraints:
$user = $this->iddqd(function () {
return $this->userManager->save($this->aUser());
});
That method would remember the current authentication, reauthenticate with ROLE_IDDQD, execute the function passed in and then restore the remembered authentication.
I'm migrating the app to Spring and looking for a way to do the same with Spring. I couldn't find any mention of ROLE_IDDQD, so I guess that part wasn't based on Spring Security. Are there any other means to replicate this functionality?
Spring security has a concept of Anonymous user with automatically assigned role "ROLE_ANONYMOUS". You can look for more information here
I solved the problem a long time ago. Here's how I did it.
In my architectures, I usually have a repository layer that abstracts away database access and a manager layer above the repository layer that enforces domain logic.
The problem was in my approach to testing. I tried to use managers to set up test data. I now do it directly using repositories and there's no need for hacks like IDDQD roles and such.
So, basically, I use repositories to populate databases with test data, and then I hit managers to test domain logic in them.

Resources