Comment changer automatiquement le code SQL généré par CodeFluent Entities, notre fabrique logicielle, afin de chiffrer et déchiffrer les valeurs stockées dans une colonne de la base de données. Ce sujet a déjà fait l’objet d’une question sur StackOverflow : comment gérer les fonctions TSQL Encrypt* and Decrypt* TSQL sur une propriété d’entité ?

Prenons ce modèle CodeFluent Entities :

code fluent entities

Un numéro de carte bancaire est une information sensible de sorte que vous devez la chiffrer avant de l’enregistrer dans la base de données. Evidemment, vous devez être en mesure de le relire et de le déchiffrer.

Découvrez dans cet article comment le faire directement dans la couche base de données.

Microsoft SQL Server 2005 (et au-delà) offre 2 nouvelles fonctions utiles : ENCRYPTBYPASSPHRASE et DECRYPTBYPASSPHRASE. Ces fonctions permettent de chiffrer et déchiffrer des données avec un mot de passe. Par exemple :

Copy to Clipboard

Tout ce que vous avez à faire est d’appeler ENCRYPTBYPASSPHRASE pendant l’enregistrement (INSERT ou UPDATE), et DECRYPTBYPASSPHRASE pendant le chargement (SELECT). Comme le code ci-après par exemple :

Copy to Clipboard

En outre, vous aurez à modifier le type de colonne de string à varbinary pour correspondre au type ENCRYPTBYPASSPHRASE.

Avec CodeFluent Entities, vous pourrez ajouter le paramètre PassPhrase aux paramètres de la procédure stockée, et pour le code généré du BOM.

Comment ?

Avant toute génération, CodeFluent Entities analyse le modèle et le transforme en une représentation complète de la mémoire qui contient des entités, des propriétés, des méthodes, des tables, des procédures, etc. Le moteur d’inférence qui effectue cette transformation utilise un pipeline qui est divisé en plusieurs étapes : les aspects peuvent être introduits à n’importe quelle étape du pipeline et sont capables de modifier le modèle en mémoire, influençant les étapes d’après.

Principales étapes du pipeline d’inférence :

La chose la plus importante à noter ici est le fait que chaque étape utilise ce qui a été créé en mémoire lors des étapes précédentes. Ainsi, si vous ajoutez une propriété assez tôt au cours de l’inférence, cette propriété sera utilisée pour créer une colonne automatiquement, toutes les méthodes standards vont utiliser cette propriété, les procédures – basées sur les méthodes – vont utiliser cette colonne et ainsi de suite.

A la fin, les générateurs (‘producteurs’ dans la terminologie CodeFluent Entities) vont transformer ce modèle mémoire en code réel, les fichiers etc.

Vous pouvez en savoir plus sur le pipeline d’inférence ici http://www.softfluent.com/documentation/Aspects_Overview.html

Concrètement

Pour faire court, un aspect est simplement une classe .NET qui implémente l’interface CodeFluent. Model. IProjectTemplate (situé dans CodeFluent. Model. dll).

Copy to Clipboard

Vous trouverez plus d’informations sur cette interface dans un post précédent http://blog.codefluententities.com/2012/07/27/codefluent-entities-writing-a-custom-aspect/

En général, un aspect déclare un espace de nommage XML spécifique, qu’il utilisera pour ces attributs spécifiques XML stockés aux côtés de ceux CodeFluent Entities. Ces attributs doivent également être déclarés. Ce n’est pas obligatoire mais c’est mieux si vous voulez les utiliser directement dans le modeleur graphique. Pour chaque attribut correspondra une ligne de grille de propriété dans la grille standard Visual Studio.

Copy to Clipboard

Lorsque l’aspect est exécuté, il doit être notifié notamment quand une propriété a été ajoutée à une entité n’importe où dans le modèle, afin de vérifier si elle doit être chiffrée. Si oui, l’entité doit être modifiée en conséquence.

L’aspect doit également être en mesure de modifier le code des procédures stockées une fois généré. L’étape d’après concerne les “ catégories ”. Cette étape doit être gérée comme suit dans le pipeline d’inférence :

Copy to Clipboard

Nous avons conçu notre aspect de telle sorte qu’il considère qu’une propriété doit être chiffrée si l’attribut XML “encrypt” (dans l’espace de nommage XML) est positionné à ‘true’ et si la propriété est persistante (disponible dans la couche de persistance). CodeFluent Entities fournit une méthode pour lire facilement les attributs de fichiers XML. Dans cet exemple, si l’attribut ‘encrypt’ n’est pas défini ou si sa valeur n’est pas convertible en une valeur booléenne, la fonction renvoie ‘false’.

Copy to Clipboard

Maintenant, la méthode OnPropertiesListChanged applique les changements nécessaires à l’ajout d’une nouvelle propriété

  • Vérifier si elle doit être chiffrée
Copy to Clipboard
  • Modifier le type de persistance pour un type binaire
Copy to Clipboard
  • Ajouter un paramètre “PassPhrase” à l’entité. Ce paramètre sera utilisé pour toutes les méthodes sans besoin de le déclarer explicitement pour chacune d’elles. Ce paramètre sera inféré automatiquement en tant que paramètre standard pour les procédures stockées avec une valeur de propriété ou méthode statique dans le BOM. Dans cet exemple, il aura une valeur d’une méthode statique arbitrairement nommée “GetPassPhrase”, décrite plus loin dans le document. Son expression (utilisée dans la partie WHERE des procédures stockées) doit également être définie. Dans la mesure où ce paramètre n’est pas réellement utilisé comme un filtre dans cet exemple, nous allons simplement mettre “ (1=1)” ce qui équivaut à un “NOP” dans une clause WHERE SQL (i. e. WHERE (([Test]. [Test_Id] = @Id) AND (1 = 1)))
Copy to Clipboard

Nous avons appliqué les changements requis dans le futur BOM et nous devons maintenant mettre à jour les procédures stockées avant de générer.

CodeFluent Entities crée un Abstract Syntax Tree (AST) pour représenter les procédures stockées. Cet AST est indépendant de la base de données cible et peut être modifié pendant l’inférence si besoin.

Pour mettre à jour cet AST, vous pouvez visiter cet arborescence (en utilisant le pattern Visiteur) et la modifier si besoin. Vous utiliserez les expressions littérales (ProcedureExpressionStatement. CreateLiteral (“Sql code”)) pour créer nos fonctions SQL ENCRYPT/DECRYPT. Dans ce cas, le code généré ne sera plus indépendant de toute plateforme. Cet aspect doit être adapté si vous souhaitez utiliser une base de données Oracle, MySQL ou PostgreSql

Copy to Clipboard

C’est terminé ! Mais appliquons à Visual Studio maintenant…

Intégrer l’aspect dans le modeler

Pour intégrer l’aspect, ajouter une référence qui contient l’aspect dans la bibliothèque de classe (elle peut être dans la même solution) :

Aspect dans le modeler 

Add external module reference

Utilisez le menu textuel de référence pour ajouter un aspect.

Menu textuel de reference

La boîte de dialogue suivante affiche les aspects disponibles dans le projet compilé à partir de cette référence :

Boite de dialogue

Pour utiliser l’aspect, un développeur doit sélectionner le concept visé et utiliser la propriété dans la grille de propriété de Visual Studio :

Team explorer

Maintenant vous pouvez construire votre modèle, ajouter la logique pour obtenir la “pass phrase”, et appréciez

Copy to Clipboard

L’intégralité du code est disponible ici

Conclusion

Avec la puissance de CodeFluent Entities et environ 180 lignes de code C#, vous avez la possibilité d’ajouter le cryptage des colonnes et les tables de la base de données de votre choix. Cet aspect est réutilisable à 100 % dans tous vos projets. Pourriez-vous faire la même chose sans CodeFluent Entities ?

Ne ratez plus aucune actualité avec la newsletter mensuelle de SoftFluent

Newsletter SoftFluent