2017-01-06 2 views
0

Dans un projet basé sur JHipster, nous devons sélectivement filtrer certaines colonnes en fonction du rôle/de l'utilisateur connecté. Tous les utilisateurs pourront voir/modifier la plupart des colonnes, mais seulement certains privilèges. les utilisateurs pourront voir/modifier certains champs/colonnes sécurisés.JHipster Masquage basé sur le rôle de certaines colonnes

Il semble que la seule option pour ce faire est d'utiliser EntityListeners. Je peux utiliser un EntityListener et masquer une certaine colonne pendant l'événement PostLoad. Dire par exemple, je masque la colonne my_secure_column avec XXX et afficher à l'utilisateur. L'utilisateur modifie ensuite d'autres champs/colonnes (auxquels il a accès) et soumet le formulaire. Dois-je à nouveau piéger l'entité partiellement remplie dans l'événement PreUpdate, obtenir la valeur d'origine pour my_secure_column de la base de données et la définir avant de persister?

Tout cela semble inefficace. Scoured plusieurs heures mais n'a pas pu trouver une implémentation spécifique qui convient le mieux à ce cas d'utilisation.

Édition 1: Cela ressemble à une première étape pour y parvenir d'une manière légèrement meilleure. Updating Entities with Update Query in Spring Data JPA

Je pourrais utiliser des mises à jour partielles spécifiques comme updateAsUserRole, updateAsManagerRole, etc., au lieu de persister toute l'entité tout le temps.

@Repository 
public interface CompanyRepository extends JpaRepository<Company, Integer> { 
    @Modifying(clearAutomatically = true) 
    @Query("UPDATE Company c SET c.address = :address WHERE c.id = :companyId") 
    int updateAddress(@Param("companyId") int companyId, @Param("address") String address); 
} 

Répondre

1

La sécurité basée sur les colonnes n'est pas un problème facile à résoudre, et en particulier en combinaison avec JPA.

Idéalement, vous souhaitez éviter de charger les colonnes, mais comme vous sélectionnez des entités, cela n'est pas possible par défaut. Vous devez donc supprimer le contenu restreint en remplaçant la valeur après le chargement. Vous pouvez également créer un bean view (POJO), puis utiliser JPQL Constructor Expression. Personnellement, j'utiliserais CriteriaBuilder. construct() au lieu de concaténer une requête JPQL, mais le même principe.

En ce qui concerne la mise à jour des données, l'interface utilisateur ne devrait pas permettre l'édition de champs restreints. Cependant, vous devez toujours valider sur le backend, et je vous recommande de vérifier si la colonne a été modifiée avant d'appeler JPA. Généralement, vous avez les modifications dans un DTO et vous devrez quand même charger l'Entité, si une colonne restreinte était modifiée, vous enverriez une erreur. De cette façon, vous appelez JPA seulement après que la sécurité a été vérifiée.

+0

Dans JHipster, généralement lors d'une mise à jour, les données sont directement liées à l'entité (il n'est pas nécessaire d'utiliser une DTO distincte). Ainsi, dans un cas normal, nous ne chargeons pas l'entité. C'est juste une mise à jour/enregistrer sur l'objet lié reçu du navigateur. Mais pour ce cas d'utilisation spécifique, il semble que nous devrons à nouveau charger l'entité, la comparer et la fusionner. Cela semble être un exercice inutile. – user1880957

+0

J'ai regardé JHipster, et même si ça vous met en route je ne l'utiliserais jamais pour la production. Comme pour toute génération de code, en essayant de construire un cadre général général, il échouera toujours (mon opinion de 13 ans). Nous avons une ressource Junior qui voulait utiliser JHipster, et cela vous donne une bonne idée des composants nécessaires, mais vous devez créer un nouveau projet et réduire la graisse - Le projet JHipster par défaut (monolitique) est de plus de 5000 lignes, généralement vous besoin de 10% de cela, le reste doit être personnalisé d'une manière ou d'une autre. Faites-vous une faveur et apprenez le printemps (Core, Boot, Sécurité, Données) –

+0

Je n'ai jamais utilisé la même classe que Entity et DTO. Je sais que la plupart des frameworks JPA offrent des services REST intégrés pour manipuler les données, mais dans mon expérience c'est une erreur. Il existe différentes exigences pour une Entité et un DTO, et vous avez souvent besoin d'une couche de sécurité avant de mettre à jour la base de données.Créer comme DTO pour vos entités est une tâche ponctuelle d'environ 1-5 minutes, ce n'est rien comparé au temps que vous passerez à gérer votre classe d'entité pour le faire faire les deux. Vous pouvez prendre ma parole à ce sujet ou l'apprendre par vous-même;) –