Un exemple de Custom Attribute

Lors d’un projet d’application Web permettant de gérer les problématiques et contraintes liées au domaine de la sécurité au travail, et après une longue période de développement, une demande a été soulevée par le client visant à permettre de crypter en base de données certaines informations stockées. Dans ce contexte de sécurisation de l’information en base, il a fallu chercher à généraliser le fonctionnement de cryptage pour le développement à effectuer les évolutions à venir.
C’est dans ce contexte que le Custom Attribute s’est révélé être un allié précieux.

.NET offre la possibilité de créer des « attributs personnalisés » de manière assez simple, ce qui permet, par exemple, d’impliciter des traitements sur des attributs d’une classe métier.

Prenons l’exemple d’une classe métier contenant des champs devant être cryptés en base de données. Il faudra appliquer à ces champs un cryptage lors de l’enregistrement de leurs valeurs mais également un décryptage pour la lecture de ces mêmes valeurs.

Nous allons utiliser un « Custom Attribute » sur notre classe Business afin d’éviter un code de ce type (où à chaque fois qu'il sera nécessaire de crypter/décrypter une valeur, il faudra faire appel à une fonction de cryptage/décryptage, ce qui serait très répétitif et pourrait poser problème en cas de modification de l'appel à ces méthodes) :

// Affichage des données
Cryptage.decrypt(Champ1) ;
Cryptage.decrypt(Champ2) ;
Cryptage.decrypt(Champ3) ;
etc…

// Enregistrement des données
Cryptage.encrypt(Champ1) ;
Cryptage.encrypt (Champ2) ;
Cryptage.encrypt (Champ3) ;
etc…

 

Il faut pour cela premièrement déclarer une classe publique qui correspondra à notre attribut, dans notre cas « EncryptedAttribute », un attribut annoté aux champs à crypter ou décrypter selon les cas.

img1

AttributeTargets.property : cet attribut ne peut s’appliquer qu’à des « properties » de notre classe, il est possible d’appliquer cela à des classes, des méthodes ou n’importe quel type (AttributeTargets.All).

A noter que cette classe est vide car elle est assez simple mais on aurait pu ici par exemple définir un constructeur, des champs, etc. pour des cas plus complexes.

Ceci étant fait, nous allons créer une classe publique chargée du cryptage et décryptage des champs annotés « Encrypted » ; cette classe sera dérivée par les classes métiers utilisant cette fonctionnalité.

img2

Ici, le mécanisme de réflexion nous permet, sans connaître la nature de l’entité, pour chacune des deux méthodes (DecryptFields et EncryptFields), de récupérer  premièrement les attributs de l’objet métier annotés « Encrypted », puis pour chacun d’eux, d’appliquer le cryptage/décryptage via une classe statique nommée EncryptDecrypt qui est la classe où sont stockées les méthodes de cryptage et décryptage.

 

La classe « EncryptedEntity » terminée, il faut à présent que notre classe métier dérive cette classe :

img3

Il ne reste plus dans notre classe métier qu’à ajouter notre attribut « Encrypted » aux champs désirés pour obtenir la classe suivante :

img4

 

Nous pouvons à présent utiliser cette méthode avant les traitements en base de données (Select, Insert, Update, etc.). Dans notre exemple, les appels au cryptage et décryptage se font dans un Repository car il n’y a aucun besoin de lire des données encore cryptées (toute lecture de ces données doit se faire après décryptage) :

img5

Dans cet exemple, nous décryptons les données immédiatement après un SELECT et nous les cryptons juste avant un INSERT.

 

Imaginons un cas où, plus tard dans le cycle de vie de l’application, de nouveaux champs apparaissent devant être cryptés, il y aura juste à ajouter l’annotation de l’attribut « Encrypted » plutôt que d’ajouter une ligne de type « Cryptage.decrypt(ChampX) ; » pour chaque écran où ce champ doit être affiché.

Grâce à cela, un temps précieux a été gagné et le projet ne pouvait rêver mieux en ce qui concerne la maintenabilité et simplicité du code lié à la problématique de sécurisation de données par cryptage en base de données.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.