Pendant environ 10 ans, j'ai travaillé sur diverses applications clientes de bureau internes avec des magasins de données SQL Server. J'ai rarement commencé ces projets - la plupart sont des travaux de reprise.
Une chose qui semblait constante partout était qu'il y avait un seul compte utilisateur global SQL Server que cette application utilisait qui lui accordait l'autorisation de la base de données commune, et oui dans certaines situations naïves, elle utilisait le sa
compte utilisateur, que j'essayais généralement de corriger lorsque cela était possible .
Vous ne pouvez pas vraiment masquer efficacement ce nom d'utilisateur et ce mot de passe que l'application utilise pour accéder à la base de données. Ils sont généralement stockés dans un ini
ou config
fichier, ou peut - être cuit dans l'exécutable lui - même. Dans tous les cas, ils sont visibles par l'utilisateur s'ils creusent un peu. Dans un cas, nous avons en fait utilisé un config
fichier mais l' avons chiffré, mais bien sûr, la clé de chiffrement devait être stockée dans l'exécutable (nous n'étions pas naïfs face aux limites de cela, mais cela a effectivement empêché les gens de fouiner qui étaient assez avertis regarder dans les config
fichiers).
Tous ces systèmes avaient un système d'authentification utilisateur intégré à l'application, mais bien sûr, ils étaient tous gérés via l'application elle-même, ce qui signifie que les informations utilisateur étaient stockées dans la base de données. L'application restreignait ce que vous pouviez faire en fonction de votre niveau d'accès, mais c'est tout un sujet de discussion si vous pouvez simplement vous connecter à la base de données et exécuter des requêtes ad hoc.
Je suis intéressé de savoir ce que font les autres systèmes pour contourner ce problème. Voici les options que je connais:
- Utilisez le mécanisme de sécurité de SQL Server pour gérer une liste d'utilisateurs et de rôles, et faire en sorte que l'application de bureau ajoute et supprime des utilisateurs via des requêtes T-SQL.
- Au lieu de vous connecter directement à la base de données, créez une sorte de service Web qui s'exécute sur le serveur et placez-y la logique d'authentification. Faites que chaque demande fasse une validation de sécurité.
La première option est un peu moche car vous séparez les utilisateurs de la base de données afin que les utilisateurs ne soient plus des entités de première classe et que vous ne puissiez pas les référencer avec des relations de clé étrangère, etc.
Le second semble juste être un problème de performance majeur, et beaucoup de travail supplémentaire, et vous ne pouvez pas utiliser aussi facilement des mappeurs ORM comme NHibernate (je pense).
Est-ce que quelqu'un a de l'expérience avec ça? Les meilleures pratiques?
Éditer
En réfléchissant un peu plus, l'authentification SQL Server peut-elle réellement résoudre ce problème? Par exemple, si votre utilisateur doit être en mesure d'insérer et de mettre à jour des enregistrements de feuille de temps afin que vous puissiez modifier votre feuille de temps, il n'y a aucun moyen que SQL Server puisse interdire l'accès aux autres lignes du tableau de détails de la feuille de temps, ce qui signifie que vous pouvez également lire et écrire les feuilles de temps d' autres personnes.
Réponses:
Je crains que l'ajout d'une couche de service Web soit probablement la bonne solution à votre problème.
Séparer le client de l'implémentation de la base de données sous-jacente vous aidera probablement aussi à long terme.
L'ajout d'une couche de service Web ne doit pas nécessairement nuire aux performances ...
En effet, avec une API appropriée, un service Web peut réellement améliorer les performances, en regroupant plusieurs requêtes de base de données dans le réseau local du centre de données, plutôt que d'exiger plusieurs allers-retours sur le WAN.
Et bien sûr, une couche de service Web peut souvent être mise à l'échelle horizontalement et ajouter une mise en cache appropriée à vos requêtes de base de données, peut-être même un mécanisme de notification de changement.
Une couche serveur ajoute une sécurité que vous ne pouvez pas garantir avec les applications s'exécutant sur un client distant. Tout ce qui s'exécute sur un client peut être «piraté» et ne doit en aucun cas être considéré comme fiable. Vous ne devez vraiment mettre la logique de présentation dans le client et héberger quoi que ce soit d'important sur le matériel dont vous avez le contrôle total.
Je ne connais pas vos applications, mais mes applications Web sont naturellement divisées en plusieurs couches, le code de présentation étant séparé de la couche de persistance par au moins un niveau de logique métier qui les sépare. Je trouve que cela rend beaucoup plus facile de raisonner sur mon application, et tellement plus rapide d'ajouter ou de modifier des fonctionnalités. Si les couches sont séparées de toute façon, il est relativement facile de garder la couche de présentation dans le client et le reste sur un serveur sous mon contrôle.
Ainsi, bien que vous puissiez résoudre vos problèmes sans introduire de couche "service Web", au moment où vous aurez écrit toutes les procédures stockées (ou équivalentes) nécessaires pour combler les trous dans l'implémentation de sécurité de base de données standard, vous feriez probablement mieux d'écrire une application côté serveur pour laquelle vous pouvez écrire des tests unitaires appropriés.
la source
Semblable à la réponse de jmoreno, vous pouvez refuser à un utilisateur l'accès à tout sauf les autorisations EXECUTE sur les procédures stockées, puis profiter du chaînage de la propriété pour que la procédure stockée effectue les opérations requises sur les tables.
Voir ici pour plus de détails https://msdn.microsoft.com/en-us/library/bb669058(v=vs.110).aspx
Lorsque l'utilisateur entre son côté client de nom d'utilisateur / mot de passe, je les stocke et envoie comme paramètres à chaque appel de procédure stockée. Vous pouvez ensuite les vérifier par rapport aux valeurs stockées dans une table avant d'effectuer l'opération souhaitée.
Ce n'est certainement pas le dernier mot en matière de sécurité, mais cela peut être nécessaire si vos PC ont des connexions génériques, limitant votre capacité à utiliser des groupes AD pour les autorisations, ou si vous avez un accès limité à AD lui-même.
la source
Une approche consiste à utiliser des groupes AD et des procédures stockées pour limiter ce que l'utilisateur peut faire - par exemple, votre base de données de feuille de temps, pourrait autoriser l'insertion, la mise à jour et la suppression des heures des utilisateurs, mais pas la mise à jour des heures de quelqu'un d'autre. L'ID de l'utilisateur serait fourni par le moteur de base de données, l'utilisateur n'aurait aucun accès direct aux tables de base de données, uniquement aux sp qui exécutaient des requêtes en fonction de leur identifiant de connexion.
Bien sûr, ce n'est pas toujours possible, mais cela peut l'être. La meilleure approche dépendra de vos besoins et de vos ressources.
la source
Ce que vous faites allusion à un «service Web» s'appelle une architecture à plusieurs niveaux . C'est généralement la voie à suivre dans les cas où des problèmes de sécurité ou de configuration sont probables (par exemple, la distribution d'une application dans de nombreux bureaux). Cependant, il ne doit pas nécessairement être basé sur le Web. Beaucoup fonctionnent avec d'autres protocoles.
Vous créez un serveur d'applications pour servir d'intermédiaire entre le client et la base de données (et d'autres ressources). Le serveur d'applications gère l'authentification basée sur votre application et effectue des actions au nom du client. En fait, idéalement, vous ne feriez pas de SQL dans votre client - vous appelez plutôt des méthodes sur le serveur d'applications. Le serveur d'applications gérerait toutes les manipulations de données.
Cette approche présente plusieurs avantages. Vous n'avez pas besoin de configurer les connexions de base de données et les pilotes sur les clients. Vous ne stockez pas les utilisateurs de base de données, les mots de passe et les serveurs. La configuration des clients n'est même pas nécessaire - il suffit de les pointer dans le code vers la bonne URL ou adresse. De plus, avec la «logique» du serveur d'applications, vous n'avez pas à vous répéter lorsque vous développez d'autres applications - le même serveur d'applications peut être réutilisé par différents types de clients.
la source
La technologie a un peu changé. Si vous authentifiez chaque utilisateur auprès de la base de données elle-même et utilisez des rôles de base de données, vous pouvez désormais utiliser ce qu'on appelle une vue actualisable pour résoudre ce problème, au moins dans SQL Server.
Voici à quoi pourrait ressembler une vue pouvant être mise à jour pour une table appelée
SomeTable
où chaque ligne de cette table est liée à un employé. L'employé doit pouvoir voir les lignes qui lui sont liées et les membres du rôle RH doivent pouvoir voir toutes les lignes, par exemple:Ensuite, vous accordez à tous les utilisateurs des autorisations de lecture (et éventuellement d'écriture) sur la vue (
vwSomeTable
) et aucune autorisation sur la table (SomeTable
).Vous pouvez tester ceci comme ceci:
... qui ne devraient renvoyer que leurs lignes. Ou:
... qui renverra toutes les lignes. Notez que vous aurez besoin des autorisations d'exécution en tant que (usurpation d'identité) pour effectuer ce test.
Les vues peuvent être mises à jour, donc même l'utilisateur ordinaire peut le faire, tant que la ligne est liée à sa
Employee
ligne:la source
L'utilisation de l'authentification par certificat est la manière "correcte" d'implémenter un compte SQL partagé. Le but est d'éliminer l'utilisation du mot de passe pour ce genre de chose.
Mise à jour:
Je suppose que j'ai mal compris la question. Je pensais que cela avait à voir avec la recherche d'une alternative à la mise en place d'un nom d'utilisateur et d'un mot de passe db soit dans une configuration d'application, soit sauvegardés dans l'application elle-même.
Vous pouvez éliminer le problème de la gestion des mots de passe dans les applications en utilisant à la place des certificats côté client. Le certificat lui-même ne suffit pas, vous devez disposer d'un système de distribution et de gestion capable d'opérations telles que la révocation du certificat.
Référence: http://en.wikipedia.org/wiki/Public-key_infrastructure
la source
Construisant une nouvelle solution de sécurité de bureau, nous avons opté pour la solution de service Web que je vais essayer de décrire ci-dessous.
Nous compilons les exécutables des applications de bureau dans un environnement distinct des développeurs. Et calculez un HASH à partir de cet exécutable qui est enregistré dans la base de données.
Un seul service Web qui fournit toutes les informations nécessaires à l'exécution de l'application, le mot de passe de la base de données, les informations sur la chaîne de connexion, les autorisations utilisateur, etc.
nous utilisons une seule connexion DB par application et enregistrons les détails de l'utilisateur dans la base de données dans des variables de session pour pouvoir auditer les enregistrements.
Une DLL gère toutes les communications entre l'application de bureau et le service Web, qui n'est accessible qu'avec une génération de jetons dans la DLL.
Pour pouvoir obtenir le mot de passe de la base de données d'application à partir du service Web, la DLL calcule les appelants DLL HASH lors de l'exécution et passe en paramètre au service Web qui valide le jeton DLL et le temps d'exécution exécutable calculé HASH à celui enregistré lors de son déploiement. (l'application n'est disponible que dans une seule installation partagée en réseau).
De cette façon, nous sommes tombés, c'est une bonne solution au problème de sécurité qui nous préoccupait le plus et connaissons bien quelques défauts de conception. Sont presque en train de terminer cette implémentation et jusqu'à présent, nous sommes satisfaits des résultats.
Edit: vous pouvez remplacer l'idée de hachage en utilisant des signatures numériques et des certificats X.509.
la source