JHipster: Persistent entities should not be used as arguments of "#RequestMapping" methods - spring-boot

guys!
I've generated an application using JHipster v7.9.3. However, when this app was evaluated by my SonarQube server, it failed.
One of the most common critical issues is the: RSPEC-4684 Persistent entities should not be used as arguments of "#RequestMapping" methods. This rule states the following:
On one side, Spring MVC automatically bind request parameters to beans declared as arguments of methods annotated with #RequestMapping. Because of this automatic binding feature, it's possible to feed some unexpected fields on the arguments of the #RequestMapping annotated methods.
On the other end, persistent objects (#Entity or #Document) are linked
to the underlying database and updated automatically by a persistence
framework, such as Hibernate, JPA or Spring Data MongoDB.
These two facts combined together can lead to malicious attack: if a persistent
object is used as an argument of a method annotated with
#RequestMapping, it's possible from a specially crafted user input, to
change the content of unexpected fields into the database.
This issue is related to CWE-915
Checking out JHipster docs, I found out this page clarifying that they really uses its domain objects (typically JPA entities) directly in its REST endpoints with the intention to make the code simpler.
I wonder if this rule is still valid or if it doesn't apply anymore for more recent Spring Boot versions (v2.7.*) and I could safely disable rule 4684 at my SonarQube.
The only reference to this rule is this one on Sonar's Jira and it is shown still as Active.

Related

Spring Boot Repository [duplicate]

I have been working with Spring Data JPA repository in my project for some time and I know the below points:
In the repository interfaces, we can add the methods like findByCustomerNameAndPhone() (assuming customerName and phone are fields in the domain object).
Then, Spring provides the implementation by implementing the above repository interface methods at runtime (during the application run).
I am interested on how this has been coded and I have looked at the Spring JPA source code & APIs, but I could not find answers to the questions below:
How is the repository implementation class generated at runtime & methods being implemented and injected?
Does Spring Data JPA use CGlib or any bytecode manipulation libraries to implement the methods and inject dynamically?
Could you please help with the above queries and also provide any supported documentation ?
First of all, there's no code generation going on, which means: no CGLib, no byte-code generation at all. The fundamental approach is that a JDK proxy instance is created programmatically using Spring's ProxyFactory API to back the interface and a MethodInterceptor intercepts all calls to the instance and routes the method into the appropriate places:
If the repository has been initialized with a custom implementation part (see that part of the reference documentation for details), and the method invoked is implemented in that class, the call is routed there.
If the method is a query method (see DefaultRepositoryInformation for how that is determined), the store specific query execution mechanism kicks in and executes the query determined to be executed for that method at startup. For that a resolution mechanism is in place that tries to identify explicitly declared queries in various places (using #Query on the method, JPA named queries) eventually falling back to query derivation from the method name. For the query mechanism detection, see JpaQueryLookupStrategy. The parsing logic for the query derivation can be found in PartTree. The store specific translation into an actual query can be seen e.g. in JpaQueryCreator.
If none of the above apply the method executed has to be one implemented by a store-specific repository base class (SimpleJpaRepository in case of JPA) and the call is routed into an instance of that.
The method interceptor implementing that routing logic is QueryExecutorMethodInterceptor, the high level routing logic can be found here.
The creation of those proxies is encapsulated into a standard Java based Factory pattern implementation. The high-level proxy creation can be found in RepositoryFactorySupport. The store-specific implementations then add the necessary infrastructure components so that for JPA you can go ahead and just write code like this:
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
The reason I mention that explicitly is that it should become clear that, in its core, nothing of that code requires a Spring container to run in the first place. It needs Spring as a library on the classpath (because we prefer to not reinvent the wheel), but is container agnostic in general.
To ease the integration with DI containers we've of course then built integration with Spring Java configuration, an XML namespace, but also a CDI extension, so that Spring Data can be used in plain CDI scenarios.

What is DDD's Aggregate in SpringBoot MVC?

Suppose I've a bunch of microservices, each written on SpringBoot MVC (REST, Controller, Service, etc..)
Can anybody explain what is DDD's Aggregate in SpringBoot MVC? is it a controller? Or is it a specific microservice which is a root for some other microservices?
In other words, is aggregate something within a service with a controller's endpoint as a root? or is aggregate a sub-set of microservices with a particular SpringBoot application/service as an entry point to them?
It is neither a controller nor specific microservice.
It is a cluster of the domain objects that can be treated as a single unit (e.g. Order and its order line) (see this) which is retrieved , saved and searched by the repository.
The spring framework also provides an more specialised #Component called #Repository to represent the repository concepts (quoted from its javadoc) :
Indicates that an annotated class is a "Repository", originally
defined by Domain-Driven Design (Evans, 2003) as "a mechanism for
encapsulating storage, retrieval, and search behavior which emulates a
collection of objects".
Teams implementing traditional Java EE
patterns such as "Data Access Object" may also apply this stereotype
to DAO classes, though care should be taken to understand the
distinction between Data Access Object and DDD-style repositories
before doing so. This annotation is a general-purpose stereotype and
individual teams may narrow their semantics and use as appropriate.
As we use repository to save JPA #Entity or MongoDB #Document to the underlying datastore , so DDD aggregate is more align to them
Two things here.
Spring MVC is a boundary layer to translate between HTTP and internals of the app. The internals are where all the DDD happens, not the boundary itself
Spring Boot is for bootstrapping an application with all the common tools and making a runnable deployment unit.
So, in case of DDD an HTTP request comes to Spring MVC layer, there a domain request is instantiated and passed to domain core for execution. Domain response then comes back and is translated into HTTP response by Spring MVC layer.

Is is recommended to use JSON Schema Validation in the place of Bean Validation JSR303 for Spring Boot Rest APIs?

Can we use JSON Schema Validation in the place of Java Bean Validation JSR303 for Spring Boot Rest APIs for Enterprise Applications? Which one is more efficient to validate request Payload to Spring Boot Rest APIs?
(i.e. performance wise, cross-validation wise and RegEx pattern based validation)
It is a good question and there are no definitive answers for it as, perhaps, it is dependent on the application domain and remains subjective to that. At the base level (which usually covers 90%) of all use cases of validating user input to the REST service, both have the equivalent facility to validate data adequately. Both support constraints which can be used to achieve the same result.
However, on one front Bean Validation stands out is its ability to define custom validators, which can be used to validate very specific domain/application dependent constraints. For example, if there is case where a class which has 3 attributes (say, A,B and C) and a constraint is required that is either A occurs or B & C occurs but not both, then it is not really possible to put a constraint in JSON schema directly, it has to be handled through design of the schema (similarly in XML, actually it is more complicated with XML).
On the other hand in Bean Validation a custom validator can be written to handle this situation quite easily.
However, these kind of cases are few and far between.
Another point to consider is the integration of the Bean Validation in the underlying framework e.g. Spring, Jersey, RESTEasy etc., JSON schema validation is not yet integrated in the frameworks.
Therefore, given the support for the tech, it is perhaps better to stick with Bean Validation 2.0 and leverage the underlying frameworks capability to validation (this is, however, purely my view).
From an application development prospect, Java bean validator is sufficient for the business needs. From a system integration point, JSON schema externalizes the business rules and provides a platform independent interface control. So if your system involves many subsystems, JSON schema gives a better way to verify message payload.
I prefer OpenAPI Specification, which can be regarded roughly as a JSON Schema dialect, to bean validation 2.0 (JSR380).
OpenAPI is the de-facto (correct me) standard to describe RESTful API today. There are tools for validation accroding to OpenAPI spec is available, an incomplete collection can be found at here. And of course it works well with Java/Spring.
OpenAPI validates JSON string rather than a POJO, thus it can handle the following case naturally while bean validation in Java cannot: say i want to validate the object in the request body of a PATCH request, and the object must have a property named A, while the value of A is can be null;
And there are more than validation you can do with an OpenAPI spec in your hand. Because an OpenAPI schema does not only define what the data model of RESTful API looks like, it also describes other aspects (endponts, parameters and status code etc.) of the API in the same file. Out there are a bunch of code generators to auto-generate server-side or client-side code to serve requests or retrive response in whatever language.

Finer control over Spring Security on Spring Data REST

I have multiple closely related problems in Spring Security. I am developing using Spring Boot and am using Spring Data REST for creating REST endpoints directly from my repositories.
I have multiple entities and the requirement is to have all these entities as REST endpoints. I am letting spring-data-rest handle the creation of these endpoints and I am securing these endpoints by adding #PreAuthorize and #PostAuthorize to the entity repository methods as and where required. This works great when I am calling an endpoint like /entity/id.
But I am facing issues from here. Let's say I have 2 entities, Entity1 and Entity2 and they have a One to One relationship. Spring data rest allows me to fetch the related Entity2 data from Entity1 like /entity1/id/entity2. But I have different access rights over Entity1 and Entity2 and calling the above endpoint only checks the access rights as set up in the repository for Entity1 only. So, if a user has access to Entity1 table and no access to Entity2 table, he can still see some Entity2 data via the foreign key relationship of Entity1. Is this a correct design?
Moreover we have some custom API endpoints wherein we have to aggregate data from multiple entity repositories. Also, these endpoints themselves have to secured. So, I am using a #PreAuthorize over an endpoint method. This works as expected and the endpoint method is called only when the expression is valid. But, when a repository method is called (via a service class of course), the #PreAuthorize over that repository method is also evaluated. I would like to have the check done with at the beginning. Is it possible to do so?
Any suggestions to improving the design is also welcome.
There is no simple solution without massively modifying/overriding lots of default Spring DataRest features. I'm working such a package for years now and it's working quite well for me.
Although switching to this package might be a bit overkill for you, it could worth the trouble in the long run because it also a fixes a lot of problem you will meet only months later.
you can set up permisison rules via annotation directly in the domain objects.
it checks the permisisons in the DB side, so the traffic between the API and DB is heavily decreased (Only those objects are fetched form the DB which the current user has permission to)
you can set READ/UPDATE/DELETE/CREATE permissions separately for roles and/or certain users
you can use pagination on permission filtered collection
you can use pagination on property-collections too
(+ some extra features like flexible search on multiple properties)
here is the package (It's an extension of Spring Data JPA / Data Rest)

Spring MVC: Recommended way to validate things that require existing Services/Repositories

Spring MVC offers form validation through both annotations on the forms (for example #NotNull) to do a simple check of the value of a field, and custom Validators, which help you do cross-field validations (verifying two password fields contain the same value, etc).
I am looking for the recommended way to do validations that go a bit further, however. For example verify if a username is not used already, which requires a call to the database. I assume I can simply inject my PersonRepository into the custom validator (which is an #Component) after all, but I doubt it'll be transactionally safe..or very clean.
What is the recommended way to do this, that requires the least amount of duplicated code? Or should I simply write my own validation layer, that throws some ValidationException with a list of validationmessages, which I have to map to the bindingresult?
To just clearify: Spring MVC don't offers form validation by itself. It integrates with Java Bean validation vendors (like Hibernate Validator).
You're right: If you configure LocalValidatorFactoryBean as a bean in your application context, you benefit from dependency management in your custom validators. In my opinion there is no need to implement a custom validation layer within your setup, since you already have a powerful and generic abstraction of validation which even conforms to Java standards.
If you worry about whether calling your repository in validator is transaction safe or not see http://docs.spring.io/spring-data/jpa/docs/1.8.2.RELEASE/reference/html/#transactions for details. CRUD operations are transactional by default. If you need a more sophisticated validation logic with needs a transaction context, you could either make your isValid(...) method transactional by annotating it, or you could autowire a business service with likely is transactional by itself. This perfectly integrate with the concepts of Spring.
Use the same business transaction
If you need to handle validation and business logic (check whether a user name is already used and insert a new if not) in the same transaction you could think about restricting those validations in Controller layer to the basic ones (#NotNull for example). This will ensure, that only syntactic correct requests make their way to your service layer.
In the service you will use an autowired validator and trigger the entire validation constraints manually. If you have a combination Hibernate as JPA vendor and Hibernate as Validation vendor you could even make use of the integration of both (pre persit and pre update events) which will cause the validation to occur automatically before the changes are written to the database.
However you decide, you will likely use validation groups to split the constraints into two groups 'syntactic' and 'semantic' for example. If you call the validator manually you can pass the groups you want to take into account. If you use integrated validation with Hibernate you can control the groups for the different events by specifying the following properties:
javax.persistence.validation.group.pre-persist
javax.persistence.validation.group.pre-update
If you decide for this way you will simply call your transactional business service method from your controller. Business logic and validation will participate in the same transaction this way.

Resources