2009-01-11 4 views
5

J'ai trop réfléchi à cela maintenant, sans solution évidente. Ce pourrait être une situation de bois pour les arbres, alors j'ai besoin de l'aide de stackoverflow. J'essaye d'imposer le filtrage de base de données sur une base régionale. Mon système a plusieurs utilisateurs et chacun est affecté à un bureau régional. Je veux seulement que les utilisateurs puissent voir les données associées à leur bureau régional.comment restreindre ou filtrer l'accès à la base de données en fonction des attributs de l'utilisateur de l'application

Mettez simplement mon application est: Java App -> JPA (veille prolongée) -> MySQL

La base de données contient l'objet de toutes les régions, mais je veux que les utilisateurs soient en mesure de manipuler des objets à partir de leur propre région. J'ai réfléchi aux manières suivantes de le faire:

1) modifier toutes les requêtes de base de données afin qu'elles lisent quelque chose comme select * de tablex où region = "myregion". C'est méchant. Cela ne fonctionne pas bien avec JPA, par exemple la méthode entitymanager.find() n'accepte que la clé primaire. Bien sûr, je peux aller natif, mais je dois seulement manquer une instruction select et ma sécurité est tirée

2) utiliser un proxy mysql pour filtrer les résultats. Un peu génial, mais alors le proxy mysql ne voit que l'appel brut et ne sait pas vraiment comment il devrait les filtrer (c'est-à-dire quelle région appartient à l'utilisateur qui a fait cette requête). Ok, je pourrais commencer un proxy pour chaque région, mais il commence à devenir un peu brouillon ..

3) utiliser des schémas séparés pour chaque région. oui, simple, j'utilise spring pour pouvoir utiliser le RoutingDataSource pour router les requêtes via la source de données correcte (1 datasource par schéma). Bien sûr, le problème est maintenant quelque part sur la ligne que je vais vouloir filtrer par région et par une autre catégorie. ohps.

4) ACL - pas vraiment sûr à ce sujet. Si a fait un select * de tablex; Est-ce qu'il filtrerait tranquillement les objets pour lesquels je n'ai pas accès ou est-ce qu'une charge d'exceptions d'accès serait levée? Mais est-ce que je réfléchis trop à ce sujet? Cela semble être un problème très commun. Il doit y avoir une solution facile que je suis trop bête pour voir. Je suis sûr que ce sera quelque chose près de/ou dans la base de données que vous voulez filtrer le plus près possible de la source, mais quoi?

Ne cherchez pas à être spoonfed - tous les liens, mots-clés, idées, suggestions de produits commerciaux/opensource seraient vraiment appréciés !! Merci.

+0

Cela semble être une de ces situations où il peut avoir payé pour écrire votre propre DAL, mais je pense que c'est hors de question pour vous. Il semble que vous deviez les filtrer au niveau des entreprises. Bonne question, j'espère que quelqu'un ici trouvera une bonne réponse. –

+0

Heureusement, j'ai un DAL très propre ... donC# 1 ressemble à la voie à suivre. Je voudrais juste être en mesure d'imposer l'utilisation de la DAL en tant que développeur dans le futur pourrait décider de le contourner –

Répondre

1

Je viens de mettre en œuvre quelque chose de similaire (REALbasic parlant à MySQL) au cours des deux dernières semaines pour une extension hiérarchique multi-entreprises à un progiciel de comptabilité. Il y a un grand nombre de code existant qui compose des instructions SQL, donc nous avons dû vivre avec cela et faire beaucoup d'audit pour nous assurer que les restrictions étaient incluses dans chaque table, le cas échéant.Un getcha était recherches connexes où les tables de recherche étaient normalement utilisées uniquement en combinaison avec une table primaire, mais pour certains GUI de maintenance chargerait directement la table de recherche elle-même.

Il y a un danger qui consiste à donner des informations implicites telles que révélant que Acme Stars de porno sont un client de quelque division de la société ;-)

La seule solution pour cette partie est la construction très minutieuse des schémas DB pour afficher toutes les des relations implicites et beaucoup de code source d'audit et de grepping, avec des commentaires attentifs pour indiquer les zones qui avaient été OK car elles ne nécessitaient pas de restrictions supplémentaires. Le modèle que j'ai inventé pour rendre ceci plus général à l'avenir est, plutôt que des recherches de type region = currentRegionVar explicite, en utilisant un entityID arbitraire fourni par une fonction globale CurrentEntityForRole ("blah").

Cette abstraction permet le partage de certaines données ainsi que la mise en œuvre de pseudo-entités qui représentent d'autres limites de restriction. Je ne connais pas assez Java et Spring pour être capable de dire, mais est-il possible d'utiliser des vues pour fournir une recherche à une seule touche, où les vues sont restreintes par le filtre de la région?

La volonté de fournir des agrégations et un éventuel partage de données était la raison pour laquelle nous ne sommes pas allés dans la base de données séparée.

+0

J'arrive à la même conclusion ... Je vais juste devoir capturer tout direct/indirect Instructions SQL pourriez-vous développer une touche sur la façon dont vous utilisez votre fonction CurrentEntityForRole() - Je ne suis pas sûr de comprendre? –

+0

"WHERE accounts.corpEntityID =" + CorporateEntities.IDforRoleQuoted ("accounts") permet d'avoir une entité différente de celle de l'utilisateur actuel. Supposons que les entreprises et les divisions partagent un plan de comptes - une division obtient la carte d'identité de sa société mère. Il mappe CurrentID + Role => effectiveID. Rarement utilisé mais utile. –

+0

vous avez eu! - Merci –

1

Bonne question.

On dirait que le n ° 1 est le meilleur car c'est le plus flexible.

La région est ce que vous filtrez aujourd'hui, mais elle pourrait être la région + département + la couleur des cheveux demain.

Si vous commencez trop à sculpter les données, il semble que vous serez obligé de travailler plus fort que nécessaire pour les regrouper et les rapporter.

0

J'ai le même problème. Il est difficile de croire qu'une telle tâche commune (filtrer une liste d'entités modèles basée sur le profil de l'utilisateur) n'a pas de façon «standard», de modèle ou de meilleure pratique pour le faire. J'ai trouvé pgacl, un module PostgreSQL. Fondamentalement, vous faites votre requête comme vous le feriez normalement, et ensuite vous activez un prédicat acl_access() pour fonctionner comme un filtre.

Peut-être qu'il y a quelque chose de similaire pour MySQL.

0

Je vous suggère d'utiliser ACL. C'est plus flexible que les autres choix. Utilisez la sécurité de printemps. Vous pouvez l'utiliser sans utiliser Spring Framework. Lisez le tutoriel de link text

Questions connexes